@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.
- package/CHANGELOG.md +15 -0
- package/LICENSE +6 -0
- package/README.md +183 -0
- package/dist/app-scope.js +92 -0
- package/dist/app-scope.js.map +1 -0
- package/dist/artifact-read.js +114 -0
- package/dist/artifact-read.js.map +1 -0
- package/dist/audit.js +36 -0
- package/dist/audit.js.map +1 -0
- package/dist/builders/artifact-type-execute.js +100 -0
- package/dist/builders/artifact-type-execute.js.map +1 -0
- package/dist/builders/artifact-type-plan.js +139 -0
- package/dist/builders/artifact-type-plan.js.map +1 -0
- package/dist/builders/design-interview.js +246 -0
- package/dist/builders/design-interview.js.map +1 -0
- package/dist/builders/entity-lifecycle-execute.js +12 -0
- package/dist/builders/entity-lifecycle-execute.js.map +1 -0
- package/dist/builders/entity-lifecycle-plan.js +345 -0
- package/dist/builders/entity-lifecycle-plan.js.map +1 -0
- package/dist/builders/links-execute.js +50 -0
- package/dist/builders/links-execute.js.map +1 -0
- package/dist/builders/links-plan.js +62 -0
- package/dist/builders/links-plan.js.map +1 -0
- package/dist/builders/page-execute.js +38 -0
- package/dist/builders/page-execute.js.map +1 -0
- package/dist/builders/page-plan.js +148 -0
- package/dist/builders/page-plan.js.map +1 -0
- package/dist/builders/records-execute.js +24 -0
- package/dist/builders/records-execute.js.map +1 -0
- package/dist/builders/records-lifecycle-execute.js +30 -0
- package/dist/builders/records-lifecycle-execute.js.map +1 -0
- package/dist/builders/records-lifecycle-plan.js +199 -0
- package/dist/builders/records-lifecycle-plan.js.map +1 -0
- package/dist/builders/records-plan.js +74 -0
- package/dist/builders/records-plan.js.map +1 -0
- package/dist/builders/update-page-execute.js +38 -0
- package/dist/builders/update-page-execute.js.map +1 -0
- package/dist/builders/update-page-plan.js +137 -0
- package/dist/builders/update-page-plan.js.map +1 -0
- package/dist/builders/workflow-execute.js +11 -0
- package/dist/builders/workflow-execute.js.map +1 -0
- package/dist/builders/workflow-plan.js +115 -0
- package/dist/builders/workflow-plan.js.map +1 -0
- package/dist/cli/client-configs.js +98 -0
- package/dist/cli/client-configs.js.map +1 -0
- package/dist/cli/login.js +64 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/prompter.js +77 -0
- package/dist/cli/prompter.js.map +1 -0
- package/dist/cli/setup.js +214 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -0
- package/dist/confirm.js +22 -0
- package/dist/confirm.js.map +1 -0
- package/dist/elwis-api.js +96 -0
- package/dist/elwis-api.js.map +1 -0
- package/dist/http-client.js +142 -0
- package/dist/http-client.js.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt.js +18 -0
- package/dist/jwt.js.map +1 -0
- package/dist/prune.js +9 -0
- package/dist/prune.js.map +1 -0
- package/dist/resolve.js +71 -0
- package/dist/resolve.js.map +1 -0
- package/dist/result.js +16 -0
- package/dist/result.js.map +1 -0
- package/dist/server.js +82 -0
- package/dist/server.js.map +1 -0
- package/dist/session-store.js +51 -0
- package/dist/session-store.js.map +1 -0
- package/dist/tools/build-artifact-type.js +36 -0
- package/dist/tools/build-artifact-type.js.map +1 -0
- package/dist/tools/build-links.js +33 -0
- package/dist/tools/build-links.js.map +1 -0
- package/dist/tools/build-page.js +40 -0
- package/dist/tools/build-page.js.map +1 -0
- package/dist/tools/build-workflow.js +36 -0
- package/dist/tools/build-workflow.js.map +1 -0
- package/dist/tools/create-application.js +44 -0
- package/dist/tools/create-application.js.map +1 -0
- package/dist/tools/create-artifacts.js +33 -0
- package/dist/tools/create-artifacts.js.map +1 -0
- package/dist/tools/create-folder.js +55 -0
- package/dist/tools/create-folder.js.map +1 -0
- package/dist/tools/delete-artifacts.js +33 -0
- package/dist/tools/delete-artifacts.js.map +1 -0
- package/dist/tools/delete-entity.js +35 -0
- package/dist/tools/delete-entity.js.map +1 -0
- package/dist/tools/explain-access.js +40 -0
- package/dist/tools/explain-access.js.map +1 -0
- package/dist/tools/get-entity.js +36 -0
- package/dist/tools/get-entity.js.map +1 -0
- package/dist/tools/get-page.js +75 -0
- package/dist/tools/get-page.js.map +1 -0
- package/dist/tools/list-apps.js +22 -0
- package/dist/tools/list-apps.js.map +1 -0
- package/dist/tools/list-entities.js +43 -0
- package/dist/tools/list-entities.js.map +1 -0
- package/dist/tools/propose-page-design.js +17 -0
- package/dist/tools/propose-page-design.js.map +1 -0
- package/dist/tools/raw-api.js +132 -0
- package/dist/tools/raw-api.js.map +1 -0
- package/dist/tools/read-artifacts.js +197 -0
- package/dist/tools/read-artifacts.js.map +1 -0
- package/dist/tools/resolve-entity.js +22 -0
- package/dist/tools/resolve-entity.js.map +1 -0
- package/dist/tools/update-artifacts.js +33 -0
- package/dist/tools/update-artifacts.js.map +1 -0
- package/dist/tools/update-entity.js +41 -0
- package/dist/tools/update-entity.js.map +1 -0
- package/dist/tools/update-page.js +40 -0
- package/dist/tools/update-page.js.map +1 -0
- package/dist/write-gate.js +25 -0
- package/dist/write-gate.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AmbiguityError, IsObjectId } from '../resolve.js';
|
|
3
|
+
import { SectionInput, MapSections } from './page-plan.js';
|
|
4
|
+
import { Prune } from '../prune.js';
|
|
5
|
+
const StyleMap = z.record(z.string(), z.union([z.string(), z.number()]));
|
|
6
|
+
export const UpdatePageInput = z.object({
|
|
7
|
+
applicationId: z.string().optional(),
|
|
8
|
+
applicationName: z.string().optional(),
|
|
9
|
+
page: z.string().min(1).describe('Page name, alias, or 24-char hex id'),
|
|
10
|
+
rename: z.string().min(1).optional().describe('New page name'),
|
|
11
|
+
alias: z.string().optional(),
|
|
12
|
+
isPublic: z.boolean().optional(),
|
|
13
|
+
sectionStyles: z
|
|
14
|
+
.array(z.object({
|
|
15
|
+
section: z.number().int().min(1).describe('1-based section number as returned by get_elwis_page'),
|
|
16
|
+
outerContainer: StyleMap.optional().describe('CSS properties for the full-width band of the section (backgrounds, vertical padding)'),
|
|
17
|
+
innerContainer: StyleMap.optional().describe('CSS properties for the centered content area of the section'),
|
|
18
|
+
replace: z.boolean().default(false).describe('false (default) merges the given properties into the existing styles; true replaces the provided container(s) entirely, leaving a container you did not pass untouched'),
|
|
19
|
+
}))
|
|
20
|
+
.optional(),
|
|
21
|
+
widgetTexts: z
|
|
22
|
+
.array(z.object({
|
|
23
|
+
widgetId: z.string().describe('Widget id from get_elwis_page; must be a TEXT widget on this page'),
|
|
24
|
+
text: z.string().describe('New HTML content, replaces the ENTIRE current content of the widget'),
|
|
25
|
+
}))
|
|
26
|
+
.optional(),
|
|
27
|
+
addSections: z
|
|
28
|
+
.array(z.object({
|
|
29
|
+
position: z.number().int().min(1).optional().describe('1-based position to insert at, evaluated AFTER removeSections have been applied (existing sections shift down); omit to append at the end'),
|
|
30
|
+
section: SectionInput,
|
|
31
|
+
}))
|
|
32
|
+
.optional(),
|
|
33
|
+
removeSections: z.array(z.number().int().min(1)).optional().describe('1-based section numbers to remove, as returned by get_elwis_page (sectionStyles and removeSections both use that original numbering)'),
|
|
34
|
+
dryRun: z.boolean().default(false).describe('Preview the resolved changes without writing anything'),
|
|
35
|
+
confirm: z.string().optional().describe('Confirmation token from the previous preview of this exact plan; required to execute when confirmation mode is on'),
|
|
36
|
+
});
|
|
37
|
+
export async function FindPage(api, applicationId, ref) {
|
|
38
|
+
if (IsObjectId(ref)) {
|
|
39
|
+
const rows = await api.list('page', { _id: { $oid: ref } });
|
|
40
|
+
if (rows.length === 0)
|
|
41
|
+
throw new Error(`No page with id "${ref}"`);
|
|
42
|
+
const page = rows[0];
|
|
43
|
+
if (String(page.applicationId) !== applicationId)
|
|
44
|
+
throw new Error(`Page "${page.name}" belongs to a different application`);
|
|
45
|
+
return page;
|
|
46
|
+
}
|
|
47
|
+
const scope = { applicationId: { $oid: applicationId } };
|
|
48
|
+
const rows = await api.list('page', { ...scope, $or: [{ name: ref }, { alias: ref }] });
|
|
49
|
+
if (rows.length === 1)
|
|
50
|
+
return rows[0];
|
|
51
|
+
if (rows.length === 0)
|
|
52
|
+
throw new Error(`No page named "${ref}" in this application`);
|
|
53
|
+
throw new AmbiguityError(`Multiple pages named "${ref}"; pass an explicit id`, rows.map(r => ({ id: r.id, name: r.name })));
|
|
54
|
+
}
|
|
55
|
+
function PageWidgetIds(page) {
|
|
56
|
+
const ids = new Set();
|
|
57
|
+
const walk = (node) => {
|
|
58
|
+
if (Array.isArray(node)) {
|
|
59
|
+
node.forEach(walk);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (node && typeof node === 'object') {
|
|
63
|
+
const obj = node;
|
|
64
|
+
if (typeof obj.widgetId === 'string')
|
|
65
|
+
ids.add(obj.widgetId);
|
|
66
|
+
Object.values(obj).forEach(walk);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
walk(page.sections);
|
|
70
|
+
return ids;
|
|
71
|
+
}
|
|
72
|
+
export async function BuildUpdatePagePlan(api, raw, applicationId) {
|
|
73
|
+
const input = UpdatePageInput.parse(raw);
|
|
74
|
+
const page = await FindPage(api, applicationId, input.page);
|
|
75
|
+
page.sections = structuredClone(page.sections);
|
|
76
|
+
const summary = [];
|
|
77
|
+
const total = page.sections.length;
|
|
78
|
+
const sectionAt = (n) => {
|
|
79
|
+
if (n > total)
|
|
80
|
+
throw new Error(`The page has ${total} section${total === 1 ? '' : 's'}; there is no section ${n}`);
|
|
81
|
+
return page.sections[n - 1];
|
|
82
|
+
};
|
|
83
|
+
const removals = [...new Set(input.removeSections ?? [])].sort((a, b) => b - a);
|
|
84
|
+
if (total - removals.length + (input.addSections?.length ?? 0) < 1)
|
|
85
|
+
throw new Error('Removing every section would leave the page empty; delete and rebuild the page instead');
|
|
86
|
+
for (const style of input.sectionStyles ?? []) {
|
|
87
|
+
if (removals.includes(style.section))
|
|
88
|
+
throw new Error(`Section ${style.section} is both styled and removed in the same call; drop one of the two`);
|
|
89
|
+
const section = sectionAt(style.section);
|
|
90
|
+
const current = (section.styles ?? {});
|
|
91
|
+
const next = style.replace
|
|
92
|
+
? {
|
|
93
|
+
outerContainer: style.outerContainer ?? current.outerContainer ?? {},
|
|
94
|
+
innerContainer: style.innerContainer ?? current.innerContainer ?? {},
|
|
95
|
+
}
|
|
96
|
+
: {
|
|
97
|
+
outerContainer: { ...(current.outerContainer ?? {}), ...(style.outerContainer ?? {}) },
|
|
98
|
+
innerContainer: { ...(current.innerContainer ?? {}), ...(style.innerContainer ?? {}) },
|
|
99
|
+
};
|
|
100
|
+
section.styles = next;
|
|
101
|
+
const parts = [style.outerContainer && `outer ${JSON.stringify(style.outerContainer)}`, style.innerContainer && `inner ${JSON.stringify(style.innerContainer)}`].filter(Boolean).join(', ');
|
|
102
|
+
summary.push(`section ${style.section}: ${style.replace ? 'replace' : 'merge'} styles, ${parts}`);
|
|
103
|
+
}
|
|
104
|
+
for (const n of removals) {
|
|
105
|
+
const section = sectionAt(n);
|
|
106
|
+
const widgetCount = (section.rows ?? []).reduce((acc, r) => acc + (r.blocks ?? []).reduce((a, b) => a + (b.parts ?? []).length, 0), 0);
|
|
107
|
+
page.sections.splice(n - 1, 1);
|
|
108
|
+
summary.push(`remove section ${n} (${widgetCount} widget${widgetCount === 1 ? '' : 's'}, their content is lost)`);
|
|
109
|
+
}
|
|
110
|
+
const newWidgets = [];
|
|
111
|
+
for (const add of input.addSections ?? []) {
|
|
112
|
+
const mapped = MapSections([add.section], newWidgets)[0];
|
|
113
|
+
const at = add.position !== undefined ? Math.min(add.position - 1, page.sections.length) : page.sections.length;
|
|
114
|
+
page.sections.splice(at, 0, mapped);
|
|
115
|
+
summary.push(`insert section at position ${at + 1}`);
|
|
116
|
+
}
|
|
117
|
+
const onPage = PageWidgetIds(page);
|
|
118
|
+
const widgetTexts = [];
|
|
119
|
+
for (const edit of input.widgetTexts ?? []) {
|
|
120
|
+
if (!onPage.has(edit.widgetId))
|
|
121
|
+
throw new Error(`Widget ${edit.widgetId} is not on page "${page.name}"; use get_elwis_page to list its widgets`);
|
|
122
|
+
const widget = await api.getOne('widget', edit.widgetId);
|
|
123
|
+
if (widget.code !== 'TEXT')
|
|
124
|
+
throw new Error(`Widget ${edit.widgetId} is a ${widget.code} widget; only text widgets can have their content replaced this way`);
|
|
125
|
+
const value = { ...(widget.value ?? {}), model: { ...(widget.value?.model ?? {}), text: edit.text } };
|
|
126
|
+
widgetTexts.push({ widgetId: edit.widgetId, code: widget.code, text: edit.text, value });
|
|
127
|
+
const excerpt = (html) => String(html ?? '').replace(/<style[\s\S]*?<\/style>/gi, '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 40);
|
|
128
|
+
summary.push(`replace content of TEXT widget ${edit.widgetId} ("${excerpt(widget.value?.model?.text)}…" -> "${excerpt(edit.text)}…")`);
|
|
129
|
+
}
|
|
130
|
+
const meta = Prune({ rename: input.rename, alias: input.alias, isPublic: input.isPublic });
|
|
131
|
+
for (const [key, value] of Object.entries(meta))
|
|
132
|
+
summary.push(`${key} -> ${JSON.stringify(value)}`);
|
|
133
|
+
if (summary.length === 0)
|
|
134
|
+
throw new Error(`Update for page "${page.name}" contains no changes; pass sectionStyles, widgetTexts, addSections, removeSections, rename, alias, or isPublic`);
|
|
135
|
+
return { page: { id: page.id, name: page.name }, sections: page.sections, newWidgets, widgetTexts, meta, summary };
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=update-page-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-page-plan.js","sourceRoot":"","sources":["../../src/builders/update-page-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HttpErrorDetail } from '../http-client.js';
|
|
2
|
+
export async function ExecuteWorkflowPlan(api, plan) {
|
|
3
|
+
try {
|
|
4
|
+
const workflow = await api.create('workflow', plan.workflowBody);
|
|
5
|
+
return { workflow: { id: workflow.id, name: workflow.name } };
|
|
6
|
+
}
|
|
7
|
+
catch (e) {
|
|
8
|
+
throw new Error(`build_workflow failed: ${e.message}${HttpErrorDetail(e)}`, { cause: e });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=workflow-execute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-execute.js","sourceRoot":"","sources":["../../src/builders/workflow-execute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMpD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAa,EAAE,IAAkB;IACzE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,CAA+B,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/F,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;IAChE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,0BAA2B,CAAW,CAAC,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IACvG,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AmbiguityError, IsObjectId, ResolveApplicationId, ResolveEntity } from '../resolve.js';
|
|
3
|
+
import { Prune } from '../prune.js';
|
|
4
|
+
const OWNER_KIND = {
|
|
5
|
+
'data-type': 'application',
|
|
6
|
+
attribute: 'application',
|
|
7
|
+
'artifact-type': 'application',
|
|
8
|
+
'link-type': 'application',
|
|
9
|
+
artifact: 'artifact-type',
|
|
10
|
+
link: 'link-type',
|
|
11
|
+
page: 'page',
|
|
12
|
+
widget: 'widget',
|
|
13
|
+
};
|
|
14
|
+
export const BuildWorkflowInput = z.object({
|
|
15
|
+
applicationId: z.string().optional(),
|
|
16
|
+
applicationName: z.string().optional(),
|
|
17
|
+
name: z.string().min(1),
|
|
18
|
+
description: z.string().optional(),
|
|
19
|
+
type: z.enum(['be', 'fe']),
|
|
20
|
+
ownerType: z.enum(['data-type', 'attribute', 'artifact-type', 'artifact', 'link-type', 'link', 'widget', 'page', 'template', 'CUSTOM']),
|
|
21
|
+
owner: z.string().optional(),
|
|
22
|
+
ownerId: z.string().optional(),
|
|
23
|
+
usedIn: z.array(z.string()).optional(),
|
|
24
|
+
defaultArtifactType: z.string().optional(),
|
|
25
|
+
global: z.boolean().default(false),
|
|
26
|
+
priority: z.number().optional(),
|
|
27
|
+
state: z.enum(['ACTIVE', 'DISABLED', 'DEVELOPMENT']).default('ACTIVE'),
|
|
28
|
+
triggers: z.array(z.record(z.string(), z.unknown())).min(1),
|
|
29
|
+
condition: z.record(z.string(), z.unknown()).nullish(),
|
|
30
|
+
actions: z.array(z.record(z.string(), z.unknown())).min(1),
|
|
31
|
+
dryRun: z.boolean().default(false),
|
|
32
|
+
confirm: z.string().optional().describe('Confirmation token from the previous preview of this exact plan; required to execute when confirmation mode is on'),
|
|
33
|
+
});
|
|
34
|
+
export async function BuildWorkflowPlan(api, raw) {
|
|
35
|
+
const input = BuildWorkflowInput.parse(raw);
|
|
36
|
+
const appRef = input.applicationId ?? input.applicationName;
|
|
37
|
+
let applicationId;
|
|
38
|
+
const application = async () => {
|
|
39
|
+
if (!appRef)
|
|
40
|
+
throw new Error('Provide applicationId or applicationName to resolve owner, usedIn or defaultArtifactType by name');
|
|
41
|
+
if (!applicationId)
|
|
42
|
+
applicationId = await ResolveApplicationId(api, appRef);
|
|
43
|
+
return applicationId;
|
|
44
|
+
};
|
|
45
|
+
const ownerId = await ResolveOwnerId(api, input, application);
|
|
46
|
+
const usedIn = await ResolveUsedIn(api, input, application, ownerId);
|
|
47
|
+
const defaultArtifactTypeId = input.defaultArtifactType
|
|
48
|
+
? await ResolveRef(api, 'artifact-type', input.defaultArtifactType, application)
|
|
49
|
+
: undefined;
|
|
50
|
+
const named = await api.list('workflow', { name: input.name });
|
|
51
|
+
const existing = ownerId ? named.find(r => String(r.ownerId) === ownerId) : named[0];
|
|
52
|
+
if (existing)
|
|
53
|
+
return { reuse: { id: existing.id, name: existing.name }, workflowBody: {} };
|
|
54
|
+
const workflowBody = Prune({
|
|
55
|
+
name: input.name,
|
|
56
|
+
description: input.description,
|
|
57
|
+
type: input.type,
|
|
58
|
+
defaultArtifactTypeId,
|
|
59
|
+
triggers: input.triggers.map(t => ({ triggerSettings: {}, ...t })),
|
|
60
|
+
ownerType: input.ownerType,
|
|
61
|
+
ownerId: ownerId,
|
|
62
|
+
usedIn: usedIn,
|
|
63
|
+
global: input.global,
|
|
64
|
+
priority: input.priority,
|
|
65
|
+
condition: input.condition ?? null,
|
|
66
|
+
state: input.state,
|
|
67
|
+
actions: input.actions.map(a => ({ actionSettings: {}, ...a })),
|
|
68
|
+
});
|
|
69
|
+
return { workflowBody };
|
|
70
|
+
}
|
|
71
|
+
async function ResolveOwnerId(api, input, application) {
|
|
72
|
+
if (input.ownerType === 'CUSTOM')
|
|
73
|
+
return null;
|
|
74
|
+
if (input.ownerId)
|
|
75
|
+
return input.ownerId;
|
|
76
|
+
const kind = OWNER_KIND[input.ownerType];
|
|
77
|
+
if (input.owner) {
|
|
78
|
+
if (IsObjectId(input.owner))
|
|
79
|
+
return input.owner;
|
|
80
|
+
if (!kind)
|
|
81
|
+
throw new AmbiguityError(`Cannot resolve owner by name for ownerType "${input.ownerType}"; pass an explicit id`, []);
|
|
82
|
+
return kind === 'application' ? ResolveApplicationId(api, input.owner) : ResolveRef(api, kind, input.owner, application);
|
|
83
|
+
}
|
|
84
|
+
if (kind === 'application')
|
|
85
|
+
return application();
|
|
86
|
+
if (input.type === 'fe')
|
|
87
|
+
return null;
|
|
88
|
+
throw new AmbiguityError(`ownerType "${input.ownerType}" requires an owner; pass owner by name or ownerId`, []);
|
|
89
|
+
}
|
|
90
|
+
async function ResolveUsedIn(api, input, application, ownerId) {
|
|
91
|
+
if (input.usedIn === undefined)
|
|
92
|
+
return ownerId ? [ownerId] : null;
|
|
93
|
+
const kind = OWNER_KIND[input.ownerType];
|
|
94
|
+
const ids = [];
|
|
95
|
+
for (const ref of input.usedIn) {
|
|
96
|
+
if (IsObjectId(ref))
|
|
97
|
+
ids.push(ref);
|
|
98
|
+
else if (!kind)
|
|
99
|
+
throw new AmbiguityError(`Cannot resolve usedIn by name for ownerType "${input.ownerType}"; pass explicit ids`, []);
|
|
100
|
+
else
|
|
101
|
+
ids.push(kind === 'application' ? await ResolveApplicationId(api, ref) : await ResolveRef(api, kind, ref, application));
|
|
102
|
+
}
|
|
103
|
+
return ids;
|
|
104
|
+
}
|
|
105
|
+
async function ResolveRef(api, kind, ref, application) {
|
|
106
|
+
if (IsObjectId(ref))
|
|
107
|
+
return ref;
|
|
108
|
+
const { matches } = await ResolveEntity(api, kind, await application(), ref);
|
|
109
|
+
if (matches.length === 1)
|
|
110
|
+
return matches[0].id;
|
|
111
|
+
if (matches.length === 0)
|
|
112
|
+
throw new AmbiguityError(`No active ${kind} named "${ref}"`, []);
|
|
113
|
+
throw new AmbiguityError(`Multiple active ${kind} named "${ref}"; pass an explicit id`, matches.map(m => ({ id: m.id, name: m.name })));
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=workflow-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-plan.js","sourceRoot":"","sources":["../../src/builders/workflow-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir, platform } from 'node:os';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
export function BuildEnv(choices) {
|
|
5
|
+
const env = { ELWIS_API_URL: choices.host };
|
|
6
|
+
if (choices.sessionToken)
|
|
7
|
+
env.ELWIS_SESSION_JWT = choices.sessionToken;
|
|
8
|
+
if (choices.tenantId)
|
|
9
|
+
env.ELWIS_TENANT = choices.tenantId;
|
|
10
|
+
if (choices.writeEnabled)
|
|
11
|
+
env.ELWIS_WRITE_ENABLED = 'true';
|
|
12
|
+
if (choices.allowedApps.length)
|
|
13
|
+
env.ELWIS_ALLOWED_APPS = choices.allowedApps.join(',');
|
|
14
|
+
return env;
|
|
15
|
+
}
|
|
16
|
+
export function ServerCommand() {
|
|
17
|
+
const self = process.argv[1] ?? '';
|
|
18
|
+
if (self.endsWith(join('dist', 'index.js')))
|
|
19
|
+
return { command: process.execPath, args: [self] };
|
|
20
|
+
return { command: 'npx', args: ['-y', '@softacus-software/elwis-data-mcp'] };
|
|
21
|
+
}
|
|
22
|
+
export function UpsertJsonClientConfig(text, entry) {
|
|
23
|
+
let root;
|
|
24
|
+
try {
|
|
25
|
+
root = text ? JSON.parse(text) : {};
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new Error('the existing configuration file is not valid JSON; fix or remove it first');
|
|
29
|
+
}
|
|
30
|
+
if (typeof root !== 'object' || root === null || Array.isArray(root))
|
|
31
|
+
throw new Error('the existing configuration file has an unexpected shape');
|
|
32
|
+
if (root.mcpServers !== undefined && (typeof root.mcpServers !== 'object' || root.mcpServers === null || Array.isArray(root.mcpServers))) {
|
|
33
|
+
throw new Error('the existing configuration file has an unexpected mcpServers shape');
|
|
34
|
+
}
|
|
35
|
+
root.mcpServers = { ...(root.mcpServers ?? {}), 'elwis-data': entry };
|
|
36
|
+
return `${JSON.stringify(root, null, 2)}\n`;
|
|
37
|
+
}
|
|
38
|
+
const OUR_TOML_HEADERS = new Set(['[mcp_servers.elwis-data]', '[mcp_servers.elwis-data.env]']);
|
|
39
|
+
export function UpsertCodexToml(text, entry) {
|
|
40
|
+
const kept = [];
|
|
41
|
+
let skipping = false;
|
|
42
|
+
for (const rawLine of (text ?? '').split(/\r?\n/)) {
|
|
43
|
+
const trimmed = rawLine.trim();
|
|
44
|
+
if (OUR_TOML_HEADERS.has(trimmed)) {
|
|
45
|
+
skipping = true;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (skipping && /^\s*\[/.test(rawLine))
|
|
49
|
+
skipping = false;
|
|
50
|
+
if (!skipping)
|
|
51
|
+
kept.push(rawLine);
|
|
52
|
+
}
|
|
53
|
+
const base = kept.join('\n').replace(/\n{3,}/g, '\n\n').trimEnd();
|
|
54
|
+
const block = [
|
|
55
|
+
'[mcp_servers.elwis-data]',
|
|
56
|
+
`command = ${JSON.stringify(entry.command)}`,
|
|
57
|
+
`args = [${entry.args.map(a => JSON.stringify(a)).join(', ')}]`,
|
|
58
|
+
'',
|
|
59
|
+
'[mcp_servers.elwis-data.env]',
|
|
60
|
+
...Object.entries(entry.env).map(([k, v]) => `${k} = ${JSON.stringify(v)}`),
|
|
61
|
+
'',
|
|
62
|
+
].join('\n');
|
|
63
|
+
return base.length ? `${base}\n\n${block}` : block;
|
|
64
|
+
}
|
|
65
|
+
export function DetectClients(home = homedir()) {
|
|
66
|
+
const claudeDesktopPath = platform() === 'win32'
|
|
67
|
+
? join(process.env.APPDATA ?? join(home, 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json')
|
|
68
|
+
: join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
69
|
+
const targets = [
|
|
70
|
+
{ id: 'claude-desktop', label: 'Claude Desktop', path: claudeDesktopPath, format: 'json', exists: false },
|
|
71
|
+
{ id: 'codex', label: 'Codex', path: join(home, '.codex', 'config.toml'), format: 'toml', exists: false },
|
|
72
|
+
{ id: 'gemini', label: 'Gemini CLI', path: join(home, '.gemini', 'settings.json'), format: 'json', exists: false },
|
|
73
|
+
];
|
|
74
|
+
for (const target of targets)
|
|
75
|
+
target.exists = existsSync(target.path) || existsSync(dirname(target.path));
|
|
76
|
+
return targets;
|
|
77
|
+
}
|
|
78
|
+
export function WriteClientConfig(target, entry) {
|
|
79
|
+
const current = existsSync(target.path) ? readFileSync(target.path, 'utf8') : null;
|
|
80
|
+
let backup = null;
|
|
81
|
+
if (current !== null) {
|
|
82
|
+
backup = `${target.path}.backup-${new Date().toISOString().replace(/[:.]/g, '-')}`;
|
|
83
|
+
copyFileSync(target.path, backup);
|
|
84
|
+
}
|
|
85
|
+
const next = target.format === 'json' ? UpsertJsonClientConfig(current, entry) : UpsertCodexToml(current, entry);
|
|
86
|
+
mkdirSync(dirname(target.path), { recursive: true });
|
|
87
|
+
if (entry.env.ELWIS_SESSION_JWT) {
|
|
88
|
+
if (current !== null)
|
|
89
|
+
chmodSync(target.path, 0o600);
|
|
90
|
+
writeFileSync(target.path, next, { mode: 0o600 });
|
|
91
|
+
chmodSync(target.path, 0o600);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
writeFileSync(target.path, next);
|
|
95
|
+
}
|
|
96
|
+
return { path: target.path, backup };
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=client-configs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-configs.js","sourceRoot":"","sources":["../../src/cli/client-configs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { stdout } from 'node:process';
|
|
2
|
+
import { CookieToken } from '../http-client.js';
|
|
3
|
+
import { SaveSession } from '../session-store.js';
|
|
4
|
+
import { Prompter } from './prompter.js';
|
|
5
|
+
export function NormalizeHost(raw) {
|
|
6
|
+
let host = raw.trim().replace(/\/+$/, '');
|
|
7
|
+
if (!/^https?:\/\//.test(host)) {
|
|
8
|
+
const local = /^(localhost|127\.0\.0\.1)([:/]|$)/.test(host);
|
|
9
|
+
host = `${local ? 'http' : 'https'}://${host}`;
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
return new URL(host).origin.toLowerCase();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return host.toLowerCase();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export async function PerformLogin(host, email, password) {
|
|
19
|
+
const response = await fetch(`${host}/api/auth/login`, {
|
|
20
|
+
method: 'POST',
|
|
21
|
+
headers: { 'Content-Type': 'application/json', Origin: host },
|
|
22
|
+
body: JSON.stringify({ email, password }),
|
|
23
|
+
});
|
|
24
|
+
const token = CookieToken(response.headers.getSetCookie());
|
|
25
|
+
if (!response.ok || !token) {
|
|
26
|
+
throw new Error(response.status === 401 || response.status === 400
|
|
27
|
+
? 'Sign-in failed, the email or password is not right. Try again.'
|
|
28
|
+
: `Sign-in failed, ELWIS answered with status ${response.status}. Check the address and try again.`);
|
|
29
|
+
}
|
|
30
|
+
const info = await fetch(`${host}/api/tenant/user/info`, { headers: { Origin: host, Cookie: `session-jwt=${token}` } });
|
|
31
|
+
const parsed = info.ok ? (await info.json()) : {};
|
|
32
|
+
const user = parsed.sessionUser;
|
|
33
|
+
return { host, token, tenantId: user?.tenant?.id ?? null, email: user?.email ?? email };
|
|
34
|
+
}
|
|
35
|
+
export async function LoginFlow(prompter, hostArg) {
|
|
36
|
+
const host = NormalizeHost(hostArg ?? (await prompter.ask('Where is your ELWIS? (address like elwis.your-company.com): ')));
|
|
37
|
+
const email = (await prompter.ask('Your ELWIS email: ')).trim();
|
|
38
|
+
const password = await prompter.askHidden('Your ELWIS password (not shown while typing): ');
|
|
39
|
+
const result = await PerformLogin(host, email, password);
|
|
40
|
+
const record = {
|
|
41
|
+
host: result.host,
|
|
42
|
+
token: result.token,
|
|
43
|
+
tenantId: result.tenantId,
|
|
44
|
+
email: result.email,
|
|
45
|
+
updatedAt: new Date().toISOString(),
|
|
46
|
+
};
|
|
47
|
+
SaveSession(record);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
export async function RunLogin(hostArg) {
|
|
51
|
+
const prompter = new Prompter();
|
|
52
|
+
try {
|
|
53
|
+
if (process.env.ELWIS_SESSION_JWT) {
|
|
54
|
+
process.stderr.write('Note: ELWIS_SESSION_JWT is set in this environment and takes priority over saved logins, the server will keep using that token until it is removed.\n');
|
|
55
|
+
}
|
|
56
|
+
const result = await LoginFlow(prompter, hostArg);
|
|
57
|
+
stdout.write(`\nSigned in as ${result.email}${result.tenantId ? ` (tenant ${result.tenantId})` : ''}.\n`);
|
|
58
|
+
stdout.write("You'll stay signed in about as long as a normal ELWIS browser login (typically two weeks). When it runs out, just sign in again.\n");
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
prompter.close();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/cli/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AASzC,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,mCAAmC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM,IAAI,EAAE,CAAC;IACjD,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,KAAa,EAAE,QAAgB;IAC9E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,iBAAiB,EAAE;QACrD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,IAAI,EAAE;QAC7D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;KAC1C,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAChE,CAAC,CAAC,gEAAgE;YAClE,CAAC,CAAC,8CAA8C,QAAQ,CAAC,MAAM,oCAAoC,CAAC,CAAC;IACzG,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,uBAAuB,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IACxH,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAoE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtH,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;IAChC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK,EAAE,CAAC;AAC1F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAkB,EAAE,OAAgB;IAClE,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC,CAAC,CAAC;IAC5H,MAAM,KAAK,GAAG,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,gDAAgD,CAAC,CAAC;IAC5F,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACzD,MAAM,MAAM,GAAkB;QAC5B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IACF,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAgB;IAC7C,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAChC,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uJAAuJ,CAAC,CAAC;QAChL,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,kBAAkB,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1G,MAAM,CAAC,KAAK,CAAC,oIAAoI,CAAC,CAAC;IACrJ,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline';
|
|
2
|
+
import { stdin, stdout } from 'node:process';
|
|
3
|
+
const CTRL_C = '';
|
|
4
|
+
const BACKSPACE = '';
|
|
5
|
+
export class Prompter {
|
|
6
|
+
rl;
|
|
7
|
+
queue = [];
|
|
8
|
+
waiters = [];
|
|
9
|
+
closed = false;
|
|
10
|
+
constructor() {
|
|
11
|
+
this.rl = createInterface({ input: stdin, terminal: stdin.isTTY === true });
|
|
12
|
+
this.rl.on('line', (line) => {
|
|
13
|
+
const waiter = this.waiters.shift();
|
|
14
|
+
if (waiter)
|
|
15
|
+
waiter(line);
|
|
16
|
+
else
|
|
17
|
+
this.queue.push(line);
|
|
18
|
+
});
|
|
19
|
+
this.rl.on('close', () => {
|
|
20
|
+
this.closed = true;
|
|
21
|
+
for (const waiter of this.waiters.splice(0))
|
|
22
|
+
waiter('');
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
ask(promptText, echoQueued = true) {
|
|
26
|
+
stdout.write(promptText);
|
|
27
|
+
const queued = this.queue.shift();
|
|
28
|
+
if (queued !== undefined) {
|
|
29
|
+
stdout.write(`${echoQueued ? queued : '***'}\n`);
|
|
30
|
+
return Promise.resolve(queued);
|
|
31
|
+
}
|
|
32
|
+
if (this.closed)
|
|
33
|
+
return Promise.resolve('');
|
|
34
|
+
return new Promise((resolveLine) => this.waiters.push(resolveLine));
|
|
35
|
+
}
|
|
36
|
+
async askHidden(promptText) {
|
|
37
|
+
if (!stdin.isTTY)
|
|
38
|
+
return (await this.ask(promptText, false)).trim();
|
|
39
|
+
stdout.write(promptText);
|
|
40
|
+
return await new Promise((resolveSecret) => {
|
|
41
|
+
const chars = [];
|
|
42
|
+
const wasRaw = stdin.isRaw;
|
|
43
|
+
stdin.setRawMode(true);
|
|
44
|
+
const finish = (value) => {
|
|
45
|
+
stdin.off('data', onData);
|
|
46
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
47
|
+
stdout.write('\n');
|
|
48
|
+
if (value === null) {
|
|
49
|
+
process.exit(130);
|
|
50
|
+
}
|
|
51
|
+
resolveSecret(value);
|
|
52
|
+
};
|
|
53
|
+
const onData = (buffer) => {
|
|
54
|
+
for (const char of buffer.toString('utf8')) {
|
|
55
|
+
if (char === CTRL_C) {
|
|
56
|
+
finish(null);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (char === '\r' || char === '\n') {
|
|
60
|
+
finish(chars.join(''));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (char === BACKSPACE || char === '\b') {
|
|
64
|
+
chars.pop();
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
chars.push(char);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
stdin.on('data', onData);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
close() {
|
|
74
|
+
this.rl.close();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=prompter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompter.js","sourceRoot":"","sources":["../../src/cli/prompter.ts"],"names":[],"mappings":"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"}
|