@saltcorn/copilot 0.7.3 → 0.7.5
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/agent-skills/pagegen.js +0 -10
- package/agent-skills/viewgen.js +229 -0
- package/builder-gen.js +1037 -24
- package/builder-schema.js +686 -0
- package/copilot-as-agent.js +1 -0
- package/index.js +2 -0
- package/package.json +1 -1
- package/standard-prompt.js +83 -0
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
const { getState } = require("@saltcorn/data/db/state");
|
|
2
|
+
|
|
3
|
+
const ACTION_SIZES = ["btn-sm", "btn-lg"];
|
|
4
|
+
const BG_TYPES = ["None", "Color", "Image", "Gradient"];
|
|
5
|
+
const IMAGE_LOCATIONS = ["Top", "Card", "Body"];
|
|
6
|
+
const IMAGE_SIZES = ["cover", "contain", "repeat"];
|
|
7
|
+
const TEXT_STYLE_OPTIONS = [
|
|
8
|
+
"h1",
|
|
9
|
+
"h2",
|
|
10
|
+
"h3",
|
|
11
|
+
"h4",
|
|
12
|
+
"h5",
|
|
13
|
+
"h6",
|
|
14
|
+
"fst-italic",
|
|
15
|
+
"text-muted",
|
|
16
|
+
"fw-bold",
|
|
17
|
+
"text-underline",
|
|
18
|
+
"small",
|
|
19
|
+
"font-monospace",
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const TOOLBOX_BY_MODE = {
|
|
23
|
+
show: [
|
|
24
|
+
"blank",
|
|
25
|
+
"columns",
|
|
26
|
+
"field",
|
|
27
|
+
"line_break",
|
|
28
|
+
"join_field",
|
|
29
|
+
"view_link",
|
|
30
|
+
"action",
|
|
31
|
+
"link",
|
|
32
|
+
"aggregation",
|
|
33
|
+
"view",
|
|
34
|
+
"container",
|
|
35
|
+
"card",
|
|
36
|
+
"tabs",
|
|
37
|
+
"image",
|
|
38
|
+
"dropdown_menu",
|
|
39
|
+
"table",
|
|
40
|
+
"page",
|
|
41
|
+
],
|
|
42
|
+
list: [
|
|
43
|
+
"blank",
|
|
44
|
+
"field",
|
|
45
|
+
"join_field",
|
|
46
|
+
"view_link",
|
|
47
|
+
"action",
|
|
48
|
+
"link",
|
|
49
|
+
"aggregation",
|
|
50
|
+
"view",
|
|
51
|
+
"container",
|
|
52
|
+
"dropdown_menu",
|
|
53
|
+
"line_break",
|
|
54
|
+
],
|
|
55
|
+
filter: [
|
|
56
|
+
"blank",
|
|
57
|
+
"columns",
|
|
58
|
+
"field",
|
|
59
|
+
"line_break",
|
|
60
|
+
"dropdown_filter",
|
|
61
|
+
"toggle_filter",
|
|
62
|
+
"search_bar",
|
|
63
|
+
"action",
|
|
64
|
+
"aggregation",
|
|
65
|
+
"container",
|
|
66
|
+
"card",
|
|
67
|
+
"tabs",
|
|
68
|
+
"view",
|
|
69
|
+
"link",
|
|
70
|
+
"table",
|
|
71
|
+
"dropdown_menu",
|
|
72
|
+
"page",
|
|
73
|
+
],
|
|
74
|
+
edit: [
|
|
75
|
+
"blank",
|
|
76
|
+
"columns",
|
|
77
|
+
"field",
|
|
78
|
+
"line_break",
|
|
79
|
+
"action",
|
|
80
|
+
"container",
|
|
81
|
+
"card",
|
|
82
|
+
"tabs",
|
|
83
|
+
"link",
|
|
84
|
+
"image",
|
|
85
|
+
"view",
|
|
86
|
+
"join_field",
|
|
87
|
+
"dropdown_menu",
|
|
88
|
+
"table",
|
|
89
|
+
"view_link",
|
|
90
|
+
],
|
|
91
|
+
page: [
|
|
92
|
+
"blank",
|
|
93
|
+
"columns",
|
|
94
|
+
"line_break",
|
|
95
|
+
"card",
|
|
96
|
+
"image",
|
|
97
|
+
"link",
|
|
98
|
+
"view",
|
|
99
|
+
"search_bar",
|
|
100
|
+
"action",
|
|
101
|
+
"container",
|
|
102
|
+
"tabs",
|
|
103
|
+
"dropdown_menu",
|
|
104
|
+
"page",
|
|
105
|
+
"table",
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const makeEnum = (values, description) => {
|
|
110
|
+
if (!values || !values.length) {
|
|
111
|
+
return { type: "string", description };
|
|
112
|
+
}
|
|
113
|
+
return { type: "string", enum: values, description };
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const buildSegmentDef = ({
|
|
117
|
+
type,
|
|
118
|
+
description,
|
|
119
|
+
properties,
|
|
120
|
+
required = [],
|
|
121
|
+
additionalProperties = true,
|
|
122
|
+
}) => ({
|
|
123
|
+
type: "object",
|
|
124
|
+
description,
|
|
125
|
+
required: ["type", ...required],
|
|
126
|
+
properties: {
|
|
127
|
+
type: { const: type, description: `Segment type: ${type}.` },
|
|
128
|
+
...properties,
|
|
129
|
+
},
|
|
130
|
+
additionalProperties,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const buildBuilderSchema = ({ mode, ctx }) => {
|
|
134
|
+
console.log({ ctx });
|
|
135
|
+
const normalizedMode = (mode || ctx?.mode || "show").toLowerCase();
|
|
136
|
+
const fields = ctx?.fields || [];
|
|
137
|
+
const actions = ctx?.actions || [];
|
|
138
|
+
const views = ctx?.viewNames || [];
|
|
139
|
+
const rawIcons = getState().icons || [];
|
|
140
|
+
const icons = (
|
|
141
|
+
Array.isArray(rawIcons) ? rawIcons : Object.keys(rawIcons)
|
|
142
|
+
).slice(0, 15);
|
|
143
|
+
|
|
144
|
+
const fieldNames = fields.map((f) => f.name).filter(Boolean);
|
|
145
|
+
const fieldviewOptions = Array.from(
|
|
146
|
+
new Set(fields.flatMap((f) => f.fieldviews || []).filter(Boolean)),
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const defs = {
|
|
150
|
+
segment: { anyOf: [] },
|
|
151
|
+
any_value: {
|
|
152
|
+
type: ["string", "number", "boolean", "object", "array", "null"],
|
|
153
|
+
description: "Any JSON value.",
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
if (fieldNames.length) {
|
|
158
|
+
defs.field_name_enum = makeEnum(fieldNames, "Field name.");
|
|
159
|
+
}
|
|
160
|
+
if (fieldviewOptions.length) {
|
|
161
|
+
defs.fieldview_enum = makeEnum(fieldviewOptions, "Field view name.");
|
|
162
|
+
}
|
|
163
|
+
if (actions.length) {
|
|
164
|
+
defs.action_name_enum = makeEnum(actions, "Action name.");
|
|
165
|
+
}
|
|
166
|
+
if (views.length) {
|
|
167
|
+
defs.view_name_enum = makeEnum(views, "View name.");
|
|
168
|
+
}
|
|
169
|
+
if (icons.length) {
|
|
170
|
+
defs.icon_enum = makeEnum(icons, "Icon name.");
|
|
171
|
+
}
|
|
172
|
+
defs.text_style_enum = makeEnum(TEXT_STYLE_OPTIONS, "Text style class name.");
|
|
173
|
+
|
|
174
|
+
defs.stack = {
|
|
175
|
+
type: "object",
|
|
176
|
+
description: "Vertical stack of segments.",
|
|
177
|
+
required: ["above"],
|
|
178
|
+
properties: {
|
|
179
|
+
above: {
|
|
180
|
+
type: "array",
|
|
181
|
+
minItems: 1,
|
|
182
|
+
items: { $ref: "#/$defs/segment" },
|
|
183
|
+
description: "Stacked segments (top to bottom).",
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
defs.columns = {
|
|
189
|
+
type: "object",
|
|
190
|
+
description: "Horizontal columns of segments.",
|
|
191
|
+
required: ["besides"],
|
|
192
|
+
properties: {
|
|
193
|
+
besides: {
|
|
194
|
+
type: "array",
|
|
195
|
+
minItems: 2,
|
|
196
|
+
items: { anyOf: [{ $ref: "#/$defs/segment" }, { type: "null" }] },
|
|
197
|
+
description: "Column segments (left to right).",
|
|
198
|
+
},
|
|
199
|
+
widths: {
|
|
200
|
+
type: "array",
|
|
201
|
+
items: { type: "integer", minimum: 1, maximum: 12 },
|
|
202
|
+
description: "Bootstrap column widths (sum to 12).",
|
|
203
|
+
},
|
|
204
|
+
breakpoints: {
|
|
205
|
+
type: "array",
|
|
206
|
+
items: { type: "string" },
|
|
207
|
+
description: "Responsive breakpoints per column.",
|
|
208
|
+
},
|
|
209
|
+
style: {
|
|
210
|
+
type: "object",
|
|
211
|
+
description: "Inline style overrides for the row.",
|
|
212
|
+
additionalProperties: true,
|
|
213
|
+
},
|
|
214
|
+
gx: { type: "number", description: "Horizontal gutter size." },
|
|
215
|
+
gy: { type: "number", description: "Vertical gutter size." },
|
|
216
|
+
customClass: { type: "string", description: "Extra CSS class names." },
|
|
217
|
+
},
|
|
218
|
+
additionalProperties: true,
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const textStyleSchema = defs.text_style_enum
|
|
222
|
+
? {
|
|
223
|
+
anyOf: [
|
|
224
|
+
{ $ref: "#/$defs/text_style_enum" },
|
|
225
|
+
{ type: "array", items: { $ref: "#/$defs/text_style_enum" } },
|
|
226
|
+
],
|
|
227
|
+
description: "Text styles (single or list).",
|
|
228
|
+
}
|
|
229
|
+
: { type: ["string", "array"], description: "Text styles." };
|
|
230
|
+
|
|
231
|
+
const backgroundProps = {
|
|
232
|
+
bgType: makeEnum(BG_TYPES, "Background type."),
|
|
233
|
+
bgColor: {
|
|
234
|
+
type: "string",
|
|
235
|
+
description: "Background color (hex).",
|
|
236
|
+
},
|
|
237
|
+
bgFileId: {
|
|
238
|
+
type: ["number", "string"],
|
|
239
|
+
description: "Background file id for images.",
|
|
240
|
+
},
|
|
241
|
+
imageLocation: makeEnum(
|
|
242
|
+
IMAGE_LOCATIONS,
|
|
243
|
+
"Image location for card/container backgrounds.",
|
|
244
|
+
),
|
|
245
|
+
imageSize: makeEnum(
|
|
246
|
+
IMAGE_SIZES,
|
|
247
|
+
"Image sizing for Card or Body locations.",
|
|
248
|
+
),
|
|
249
|
+
gradStartColor: {
|
|
250
|
+
type: "string",
|
|
251
|
+
description: "Gradient start color (hex).",
|
|
252
|
+
},
|
|
253
|
+
gradEndColor: {
|
|
254
|
+
type: "string",
|
|
255
|
+
description: "Gradient end color (hex).",
|
|
256
|
+
},
|
|
257
|
+
gradDirection: {
|
|
258
|
+
type: ["number", "string"],
|
|
259
|
+
description: "Gradient direction (degrees).",
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const blankDef = buildSegmentDef({
|
|
264
|
+
type: "blank",
|
|
265
|
+
description: "Plain text block.",
|
|
266
|
+
properties: {
|
|
267
|
+
contents: { type: "string", description: "Text contents." },
|
|
268
|
+
block: { type: "boolean", description: "Render as block element." },
|
|
269
|
+
inline: { type: "boolean", description: "Render inline." },
|
|
270
|
+
textStyle: textStyleSchema,
|
|
271
|
+
labelFor: { type: "string", description: "Label for field name." },
|
|
272
|
+
customClass: { type: "string", description: "Extra CSS class names." },
|
|
273
|
+
style: {
|
|
274
|
+
type: "object",
|
|
275
|
+
description: "Inline style overrides.",
|
|
276
|
+
additionalProperties: true,
|
|
277
|
+
},
|
|
278
|
+
icon: defs.icon_enum
|
|
279
|
+
? { $ref: "#/$defs/icon_enum", description: "Optional icon." }
|
|
280
|
+
: { type: "string", description: "Optional icon." },
|
|
281
|
+
font: { type: "string", description: "Font family name." },
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const fieldDef = buildSegmentDef({
|
|
286
|
+
type: "field",
|
|
287
|
+
description: "Field segment.",
|
|
288
|
+
properties: {
|
|
289
|
+
field_name: defs.field_name_enum
|
|
290
|
+
? { $ref: "#/$defs/field_name_enum", description: "Field name." }
|
|
291
|
+
: { type: "string", description: "Field name." },
|
|
292
|
+
fieldview: defs.fieldview_enum
|
|
293
|
+
? { $ref: "#/$defs/fieldview_enum", description: "Field view." }
|
|
294
|
+
: { type: "string", description: "Field view." },
|
|
295
|
+
configuration: {
|
|
296
|
+
type: "object",
|
|
297
|
+
description: "Fieldview configuration.",
|
|
298
|
+
additionalProperties: true,
|
|
299
|
+
},
|
|
300
|
+
textStyle: textStyleSchema,
|
|
301
|
+
block: { type: "boolean", description: "Render as block element." },
|
|
302
|
+
inline: { type: "boolean", description: "Render inline." },
|
|
303
|
+
class: { type: "string", description: "Extra CSS class names." },
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
const actionDef = buildSegmentDef({
|
|
308
|
+
type: "action",
|
|
309
|
+
description: "Action button segment.",
|
|
310
|
+
properties: {
|
|
311
|
+
action_name: defs.action_name_enum
|
|
312
|
+
? { $ref: "#/$defs/action_name_enum", description: "Action name." }
|
|
313
|
+
: { type: "string", description: "Action name." },
|
|
314
|
+
action_label: { type: "string", description: "Button label." },
|
|
315
|
+
action_style: { type: "string", description: "Button style class." },
|
|
316
|
+
action_size: {
|
|
317
|
+
type: "string",
|
|
318
|
+
enum: ACTION_SIZES,
|
|
319
|
+
description: "Button size class.",
|
|
320
|
+
},
|
|
321
|
+
action_icon: defs.icon_enum
|
|
322
|
+
? { $ref: "#/$defs/icon_enum", description: "Optional icon." }
|
|
323
|
+
: { type: "string", description: "Optional icon." },
|
|
324
|
+
action_class: { type: "string", description: "Extra CSS class names." },
|
|
325
|
+
action_title: { type: "string", description: "Button title text." },
|
|
326
|
+
action_bgcol: { type: "string", description: "Button background color." },
|
|
327
|
+
action_bordercol: {
|
|
328
|
+
type: "string",
|
|
329
|
+
description: "Button border color.",
|
|
330
|
+
},
|
|
331
|
+
action_textcol: { type: "string", description: "Button text color." },
|
|
332
|
+
confirm: { type: "string", description: "Confirmation prompt." },
|
|
333
|
+
minRole: { type: "number", description: "Minimum role id." },
|
|
334
|
+
nsteps: { type: "number", description: "Number of workflow steps." },
|
|
335
|
+
configuration: {
|
|
336
|
+
type: "object",
|
|
337
|
+
description: "Action configuration.",
|
|
338
|
+
additionalProperties: true,
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
const viewDef = buildSegmentDef({
|
|
344
|
+
type: "view",
|
|
345
|
+
description: "Embedded view.",
|
|
346
|
+
properties: {
|
|
347
|
+
view: defs.view_name_enum
|
|
348
|
+
? { $ref: "#/$defs/view_name_enum", description: "View name." }
|
|
349
|
+
: { type: "string", description: "View name." },
|
|
350
|
+
state: {
|
|
351
|
+
type: "object",
|
|
352
|
+
description: "View state overrides.",
|
|
353
|
+
additionalProperties: true,
|
|
354
|
+
},
|
|
355
|
+
relation: { type: "string", description: "Relation name." },
|
|
356
|
+
order_field: { type: "string", description: "Order field name." },
|
|
357
|
+
view_name: { type: "string", description: "View name override." },
|
|
358
|
+
name: { type: "string", description: "View instance name." },
|
|
359
|
+
configuration: {
|
|
360
|
+
type: "object",
|
|
361
|
+
description: "View configuration.",
|
|
362
|
+
additionalProperties: true,
|
|
363
|
+
},
|
|
364
|
+
extra_state_fml: {
|
|
365
|
+
type: "string",
|
|
366
|
+
description: "Extra state formula.",
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
const viewLinkDef = buildSegmentDef({
|
|
372
|
+
type: "view_link",
|
|
373
|
+
description: "Link to a view.",
|
|
374
|
+
properties: {
|
|
375
|
+
view: defs.view_name_enum
|
|
376
|
+
? { $ref: "#/$defs/view_name_enum", description: "View name." }
|
|
377
|
+
: { type: "string", description: "View name." },
|
|
378
|
+
view_label: { type: "string", description: "Link label." },
|
|
379
|
+
link_style: { type: "string", description: "Link style class." },
|
|
380
|
+
class: { type: "string", description: "Extra CSS class names." },
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
const containerDef = buildSegmentDef({
|
|
385
|
+
type: "container",
|
|
386
|
+
description: "Container wrapper.",
|
|
387
|
+
properties: {
|
|
388
|
+
contents: { $ref: "#/$defs/segment", description: "Nested contents." },
|
|
389
|
+
class: { type: "string", description: "Extra CSS class names." },
|
|
390
|
+
customClass: { type: "string", description: "Custom CSS class names." },
|
|
391
|
+
style: {
|
|
392
|
+
type: "object",
|
|
393
|
+
description: "Inline style overrides.",
|
|
394
|
+
additionalProperties: true,
|
|
395
|
+
},
|
|
396
|
+
...backgroundProps,
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
const cardDef = buildSegmentDef({
|
|
401
|
+
type: "card",
|
|
402
|
+
description: "Card wrapper.",
|
|
403
|
+
properties: {
|
|
404
|
+
title: { type: "string", description: "Card title." },
|
|
405
|
+
contents: { $ref: "#/$defs/segment", description: "Card contents." },
|
|
406
|
+
class: { type: "string", description: "Extra CSS class names." },
|
|
407
|
+
customClass: { type: "string", description: "Custom CSS class names." },
|
|
408
|
+
style: {
|
|
409
|
+
type: "object",
|
|
410
|
+
description: "Inline style overrides.",
|
|
411
|
+
additionalProperties: true,
|
|
412
|
+
},
|
|
413
|
+
shadow: { type: "boolean", description: "Enable card shadow." },
|
|
414
|
+
noPadding: { type: "boolean", description: "Disable card padding." },
|
|
415
|
+
hasFooter: { type: "boolean", description: "Enable footer area." },
|
|
416
|
+
...backgroundProps,
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
const tabsDef = buildSegmentDef({
|
|
421
|
+
type: "tabs",
|
|
422
|
+
description: "Tabbed content.",
|
|
423
|
+
properties: {
|
|
424
|
+
contents: {
|
|
425
|
+
type: "array",
|
|
426
|
+
items: { $ref: "#/$defs/segment" },
|
|
427
|
+
description: "Tab contents array.",
|
|
428
|
+
},
|
|
429
|
+
titles: {
|
|
430
|
+
type: "array",
|
|
431
|
+
items: { type: "object" },
|
|
432
|
+
description: "Tab titles array.",
|
|
433
|
+
},
|
|
434
|
+
tabs: {
|
|
435
|
+
type: "array",
|
|
436
|
+
items: {
|
|
437
|
+
type: "object",
|
|
438
|
+
properties: {
|
|
439
|
+
title: { type: "string" },
|
|
440
|
+
contents: { $ref: "#/$defs/segment" },
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
description: "Tabs with explicit titles and contents.",
|
|
444
|
+
},
|
|
445
|
+
class: { type: "string", description: "Extra CSS class names." },
|
|
446
|
+
},
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
const imageDef = buildSegmentDef({
|
|
450
|
+
type: "image",
|
|
451
|
+
description: "Image segment.",
|
|
452
|
+
properties: {
|
|
453
|
+
url: { type: "string", description: "Image URL or file path." },
|
|
454
|
+
src: { type: "string", description: "Image src alias." },
|
|
455
|
+
alt: { type: "string", description: "Alt text." },
|
|
456
|
+
class: { type: "string", description: "Extra CSS class names." },
|
|
457
|
+
style: {
|
|
458
|
+
type: "object",
|
|
459
|
+
description: "Inline style overrides.",
|
|
460
|
+
additionalProperties: true,
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
const linkDef = buildSegmentDef({
|
|
466
|
+
type: "link",
|
|
467
|
+
description: "Link segment.",
|
|
468
|
+
properties: {
|
|
469
|
+
url: { type: "string", description: "Link URL." },
|
|
470
|
+
text: { type: "string", description: "Link text." },
|
|
471
|
+
link_style: { type: "string", description: "Link style class." },
|
|
472
|
+
class: { type: "string", description: "Extra CSS class names." },
|
|
473
|
+
icon: defs.icon_enum
|
|
474
|
+
? { $ref: "#/$defs/icon_enum", description: "Optional icon." }
|
|
475
|
+
: { type: "string", description: "Optional icon." },
|
|
476
|
+
},
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
const lineBreakDef = buildSegmentDef({
|
|
480
|
+
type: "line_break",
|
|
481
|
+
description: "Line break / divider.",
|
|
482
|
+
properties: {
|
|
483
|
+
class: { type: "string", description: "Extra CSS class names." },
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
const searchBarDef = buildSegmentDef({
|
|
488
|
+
type: "search_bar",
|
|
489
|
+
description: "Search bar segment.",
|
|
490
|
+
properties: {
|
|
491
|
+
class: { type: "string", description: "Extra CSS class names." },
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
const tableDef = buildSegmentDef({
|
|
496
|
+
type: "table",
|
|
497
|
+
description: "Table layout segment.",
|
|
498
|
+
properties: {
|
|
499
|
+
rows: { type: "integer", description: "Number of rows." },
|
|
500
|
+
columns: { type: "integer", description: "Number of columns." },
|
|
501
|
+
contents: {
|
|
502
|
+
type: "array",
|
|
503
|
+
items: {
|
|
504
|
+
type: "array",
|
|
505
|
+
items: { $ref: "#/$defs/segment" },
|
|
506
|
+
},
|
|
507
|
+
description: "Row/column contents as nested segments.",
|
|
508
|
+
},
|
|
509
|
+
bs_style: { type: "string", description: "Bootstrap table style." },
|
|
510
|
+
bs_small: { type: "boolean", description: "Small table style." },
|
|
511
|
+
bs_striped: { type: "boolean", description: "Striped rows." },
|
|
512
|
+
bs_bordered: { type: "boolean", description: "Bordered table." },
|
|
513
|
+
bs_borderless: { type: "boolean", description: "Borderless table." },
|
|
514
|
+
bs_wauto: { type: "boolean", description: "Auto width table." },
|
|
515
|
+
customClass: { type: "string", description: "Extra CSS class names." },
|
|
516
|
+
},
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
const aggregationDef = buildSegmentDef({
|
|
520
|
+
type: "aggregation",
|
|
521
|
+
description: "Aggregation segment.",
|
|
522
|
+
properties: {
|
|
523
|
+
agg_relation: { type: "string", description: "Aggregation relation." },
|
|
524
|
+
agg_field: { type: "string", description: "Aggregation field." },
|
|
525
|
+
agg_func: { type: "string", description: "Aggregation function." },
|
|
526
|
+
label: { type: "string", description: "Label text." },
|
|
527
|
+
},
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
const dropdownFilterDef = buildSegmentDef({
|
|
531
|
+
type: "dropdown_filter",
|
|
532
|
+
description: "Dropdown filter segment.",
|
|
533
|
+
properties: {
|
|
534
|
+
field_name: defs.field_name_enum
|
|
535
|
+
? { $ref: "#/$defs/field_name_enum", description: "Field name." }
|
|
536
|
+
: { type: "string", description: "Field name." },
|
|
537
|
+
label: { type: "string", description: "Label text." },
|
|
538
|
+
},
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
const toggleFilterDef = buildSegmentDef({
|
|
542
|
+
type: "toggle_filter",
|
|
543
|
+
description: "Toggle filter segment.",
|
|
544
|
+
properties: {
|
|
545
|
+
field_name: defs.field_name_enum
|
|
546
|
+
? { $ref: "#/$defs/field_name_enum", description: "Field name." }
|
|
547
|
+
: { type: "string", description: "Field name." },
|
|
548
|
+
label: { type: "string", description: "Label text." },
|
|
549
|
+
},
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
const dropdownMenuDef = buildSegmentDef({
|
|
553
|
+
type: "dropdown_menu",
|
|
554
|
+
description: "Dropdown menu segment.",
|
|
555
|
+
properties: {
|
|
556
|
+
label: { type: "string", description: "Menu label." },
|
|
557
|
+
class: { type: "string", description: "Extra CSS class names." },
|
|
558
|
+
},
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
const joinFieldDef = buildSegmentDef({
|
|
562
|
+
type: "join_field",
|
|
563
|
+
description: "Join field segment.",
|
|
564
|
+
properties: {
|
|
565
|
+
field_name: defs.field_name_enum
|
|
566
|
+
? { $ref: "#/$defs/field_name_enum", description: "Field name." }
|
|
567
|
+
: { type: "string", description: "Field name." },
|
|
568
|
+
view: defs.view_name_enum
|
|
569
|
+
? { $ref: "#/$defs/view_name_enum", description: "View name." }
|
|
570
|
+
: { type: "string", description: "View name." },
|
|
571
|
+
label: { type: "string", description: "Label text." },
|
|
572
|
+
},
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
const listColumnDef = buildSegmentDef({
|
|
576
|
+
type: "list_column",
|
|
577
|
+
description: "List column segment.",
|
|
578
|
+
properties: {
|
|
579
|
+
contents: { $ref: "#/$defs/segment", description: "Column contents." },
|
|
580
|
+
col_width: { type: "number", description: "Column width value." },
|
|
581
|
+
col_width_units: { type: "string", description: "Width units." },
|
|
582
|
+
alignment: { type: "string", description: "Text alignment." },
|
|
583
|
+
header_label: { type: "string", description: "Header label." },
|
|
584
|
+
showif: { type: "string", description: "Show-if formula." },
|
|
585
|
+
},
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
const listColumnsDef = buildSegmentDef({
|
|
589
|
+
type: "list_columns",
|
|
590
|
+
description: "List columns wrapper.",
|
|
591
|
+
properties: {
|
|
592
|
+
besides: {
|
|
593
|
+
type: "array",
|
|
594
|
+
items: { $ref: "#/$defs/segment" },
|
|
595
|
+
description: "List column segments.",
|
|
596
|
+
},
|
|
597
|
+
list_columns: {
|
|
598
|
+
type: "boolean",
|
|
599
|
+
description: "Marks list columns container.",
|
|
600
|
+
},
|
|
601
|
+
},
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
const pageDef = buildSegmentDef({
|
|
605
|
+
type: "page",
|
|
606
|
+
description: "Page embed segment.",
|
|
607
|
+
properties: {
|
|
608
|
+
page: { type: "string", description: "Page name." },
|
|
609
|
+
title: { type: "string", description: "Page title." },
|
|
610
|
+
},
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
defs.segment.anyOf.push(
|
|
614
|
+
{ $ref: "#/$defs/stack" },
|
|
615
|
+
{ $ref: "#/$defs/columns" },
|
|
616
|
+
{ $ref: "#/$defs/blank" },
|
|
617
|
+
{ $ref: "#/$defs/field" },
|
|
618
|
+
{ $ref: "#/$defs/action" },
|
|
619
|
+
{ $ref: "#/$defs/view" },
|
|
620
|
+
{ $ref: "#/$defs/view_link" },
|
|
621
|
+
{ $ref: "#/$defs/container" },
|
|
622
|
+
{ $ref: "#/$defs/card" },
|
|
623
|
+
{ $ref: "#/$defs/tabs" },
|
|
624
|
+
{ $ref: "#/$defs/image" },
|
|
625
|
+
{ $ref: "#/$defs/link" },
|
|
626
|
+
{ $ref: "#/$defs/line_break" },
|
|
627
|
+
{ $ref: "#/$defs/search_bar" },
|
|
628
|
+
{ $ref: "#/$defs/table" },
|
|
629
|
+
{ $ref: "#/$defs/aggregation" },
|
|
630
|
+
{ $ref: "#/$defs/dropdown_filter" },
|
|
631
|
+
{ $ref: "#/$defs/toggle_filter" },
|
|
632
|
+
{ $ref: "#/$defs/dropdown_menu" },
|
|
633
|
+
{ $ref: "#/$defs/join_field" },
|
|
634
|
+
{ $ref: "#/$defs/list_column" },
|
|
635
|
+
{ $ref: "#/$defs/list_columns" },
|
|
636
|
+
{ $ref: "#/$defs/page" },
|
|
637
|
+
);
|
|
638
|
+
|
|
639
|
+
Object.assign(defs, {
|
|
640
|
+
blank: blankDef,
|
|
641
|
+
field: fieldDef,
|
|
642
|
+
action: actionDef,
|
|
643
|
+
view: viewDef,
|
|
644
|
+
view_link: viewLinkDef,
|
|
645
|
+
container: containerDef,
|
|
646
|
+
card: cardDef,
|
|
647
|
+
tabs: tabsDef,
|
|
648
|
+
image: imageDef,
|
|
649
|
+
link: linkDef,
|
|
650
|
+
line_break: lineBreakDef,
|
|
651
|
+
search_bar: searchBarDef,
|
|
652
|
+
table: tableDef,
|
|
653
|
+
aggregation: aggregationDef,
|
|
654
|
+
dropdown_filter: dropdownFilterDef,
|
|
655
|
+
toggle_filter: toggleFilterDef,
|
|
656
|
+
dropdown_menu: dropdownMenuDef,
|
|
657
|
+
join_field: joinFieldDef,
|
|
658
|
+
list_column: listColumnDef,
|
|
659
|
+
list_columns: listColumnsDef,
|
|
660
|
+
page: pageDef,
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
return {
|
|
664
|
+
schema: {
|
|
665
|
+
type: "object",
|
|
666
|
+
required: ["layout"],
|
|
667
|
+
properties: {
|
|
668
|
+
layout: { $ref: "#/$defs/segment" },
|
|
669
|
+
},
|
|
670
|
+
$defs: defs,
|
|
671
|
+
},
|
|
672
|
+
meta: {
|
|
673
|
+
mode: normalizedMode,
|
|
674
|
+
table: ctx?.table ? { id: ctx.table.id, name: ctx.table.name } : null,
|
|
675
|
+
allowedComponents: TOOLBOX_BY_MODE[normalizedMode] || [],
|
|
676
|
+
fields: fields.map((f) => ({ name: f.name, label: f.label })),
|
|
677
|
+
actions,
|
|
678
|
+
views,
|
|
679
|
+
},
|
|
680
|
+
};
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
module.exports = {
|
|
684
|
+
buildBuilderSchema,
|
|
685
|
+
TOOLBOX_BY_MODE,
|
|
686
|
+
};
|
package/copilot-as-agent.js
CHANGED
package/index.js
CHANGED
|
@@ -14,6 +14,7 @@ module.exports = {
|
|
|
14
14
|
: [require("./action-builder"), require("./database-designer")],
|
|
15
15
|
functions: features.workflows
|
|
16
16
|
? {
|
|
17
|
+
copilot_standard_prompt: require("./standard-prompt.js"),
|
|
17
18
|
copilot_generate_layout: require("./builder-gen.js"),
|
|
18
19
|
copilot_generate_workflow: require("./workflow-gen"),
|
|
19
20
|
}
|
|
@@ -24,6 +25,7 @@ module.exports = {
|
|
|
24
25
|
require("./agent-skills/pagegen.js"),
|
|
25
26
|
require("./agent-skills/database-design.js"),
|
|
26
27
|
require("./agent-skills/workflow.js"),
|
|
28
|
+
require("./agent-skills/viewgen.js"),
|
|
27
29
|
],
|
|
28
30
|
},
|
|
29
31
|
};
|