@melius-ai/cli 0.9.1 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/dist/bin/mel.js +1 -1
- package/dist/{chunk-WRLYKNYI.js → chunk-NNJE574V.js} +312 -19
- package/dist/src/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -203,6 +203,31 @@ mel preset apply <canvasId> <presetId>
|
|
|
203
203
|
mel bulk-run start <canvasId> --wait
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
+
### Templates
|
|
207
|
+
|
|
208
|
+
Templates are reusable workflows applied server-side as collapsed boxes. Listing includes global templates and templates scoped to the current team. The CLI exposes only template metadata, declared ports, and the applied box IDs; internal workflow nodes and configuration stay private.
|
|
209
|
+
|
|
210
|
+
| Command | Description |
|
|
211
|
+
| -------------------------------------------- | ------------------------------------------------------------------------ |
|
|
212
|
+
| `mel template list` | List available templates and their declared input/output ports |
|
|
213
|
+
| `mel template apply <canvasId> <templateId>` | Apply a template as one collapsed box and return `instanceId`, `groupId` |
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Discover templates and ports
|
|
217
|
+
mel template list
|
|
218
|
+
mel template list --fields id,title,inputPorts,outputPorts
|
|
219
|
+
|
|
220
|
+
# Apply with automatic placement
|
|
221
|
+
mel template apply <canvasId> <templateId>
|
|
222
|
+
|
|
223
|
+
# Materialize a text input while applying
|
|
224
|
+
mel template apply <canvasId> <templateId> \
|
|
225
|
+
--inputs '[{"kind":"text","portId":"<portId>","text":"A red shoe"}]'
|
|
226
|
+
|
|
227
|
+
# Run only the opaque template box
|
|
228
|
+
mel bulk-run start <canvasId> --node-ids <groupId> --wait
|
|
229
|
+
```
|
|
230
|
+
|
|
206
231
|
### Models
|
|
207
232
|
|
|
208
233
|
| Command | Description |
|
package/dist/bin/mel.js
CHANGED
|
@@ -8647,12 +8647,17 @@ var AgentMessageFeedbackResponseSchema = external_exports.object({
|
|
|
8647
8647
|
createdAt: external_exports.string().datetime()
|
|
8648
8648
|
});
|
|
8649
8649
|
var AgentSessionStatusSchema = external_exports.enum(["active", "ended", "error"]);
|
|
8650
|
+
var AgentSessionSourceSchema = external_exports.enum(["web", "slack"]);
|
|
8650
8651
|
var AgentSessionResponseSchema = external_exports.object({
|
|
8651
8652
|
id: external_exports.string().uuid(),
|
|
8652
8653
|
userId: external_exports.string().uuid(),
|
|
8653
8654
|
teamId: external_exports.string().uuid(),
|
|
8654
8655
|
title: external_exports.string(),
|
|
8655
8656
|
status: AgentSessionStatusSchema,
|
|
8657
|
+
/** Optional so web clients remain compatible with servers that predate session sources. */
|
|
8658
|
+
source: AgentSessionSourceSchema.optional(),
|
|
8659
|
+
/** True when this transcript is view-only on the current surface. */
|
|
8660
|
+
readOnly: external_exports.boolean().optional(),
|
|
8656
8661
|
/** True when the agent is actively generating a response. */
|
|
8657
8662
|
isGenerating: external_exports.boolean(),
|
|
8658
8663
|
/** Present when the session is waiting for the user to approve a tool call. */
|
|
@@ -8781,6 +8786,28 @@ var agentContract = c3.router({
|
|
|
8781
8786
|
},
|
|
8782
8787
|
summary: "Get an agent session with recent messages"
|
|
8783
8788
|
},
|
|
8789
|
+
getInternalDemoCanvasSession: {
|
|
8790
|
+
method: "GET",
|
|
8791
|
+
path: "/agent/internal-demo-canvas-sessions/:sessionId",
|
|
8792
|
+
pathParams: external_exports.object({ sessionId: external_exports.string().uuid() }),
|
|
8793
|
+
query: external_exports.object({
|
|
8794
|
+
messageLimit: external_exports.coerce.number().int().min(0).max(100).default(50)
|
|
8795
|
+
}),
|
|
8796
|
+
responses: {
|
|
8797
|
+
200: AgentSessionResponseSchema
|
|
8798
|
+
},
|
|
8799
|
+
summary: "Get an internal demo canvas Slack transcript"
|
|
8800
|
+
},
|
|
8801
|
+
forkInternalDemoCanvasSession: {
|
|
8802
|
+
method: "POST",
|
|
8803
|
+
path: "/agent/internal-demo-canvas-sessions/:sessionId/fork",
|
|
8804
|
+
pathParams: external_exports.object({ sessionId: external_exports.string().uuid() }),
|
|
8805
|
+
body: null,
|
|
8806
|
+
responses: {
|
|
8807
|
+
201: AgentSessionResponseSchema
|
|
8808
|
+
},
|
|
8809
|
+
summary: "Fork an internal demo canvas Slack transcript into a private agent session"
|
|
8810
|
+
},
|
|
8784
8811
|
renameSession: {
|
|
8785
8812
|
method: "PATCH",
|
|
8786
8813
|
path: "/agent/sessions/:sessionId",
|
|
@@ -10221,7 +10248,21 @@ var PreviewAssetSchema = external_exports.object({
|
|
|
10221
10248
|
thumbnailUrl: external_exports.string().nullable()
|
|
10222
10249
|
});
|
|
10223
10250
|
|
|
10251
|
+
// ../api-contract/src/template-port-summary.ts
|
|
10252
|
+
var TemplatePortSummarySchema = external_exports.object({
|
|
10253
|
+
id: external_exports.string(),
|
|
10254
|
+
direction: external_exports.enum(["input", "output"]),
|
|
10255
|
+
label: external_exports.string(),
|
|
10256
|
+
handleType: external_exports.string(),
|
|
10257
|
+
required: external_exports.boolean().optional(),
|
|
10258
|
+
maxConnections: external_exports.number().int().positive().optional(),
|
|
10259
|
+
outputAspectRatio: external_exports.enum(ASPECT_RATIOS).nullable().optional(),
|
|
10260
|
+
exampleAssetUrl: external_exports.string().nullable().optional(),
|
|
10261
|
+
exampleText: external_exports.string().nullable().optional()
|
|
10262
|
+
});
|
|
10263
|
+
|
|
10224
10264
|
// ../api-contract/src/templates-ports.ts
|
|
10265
|
+
var TEMPLATE_EXAMPLE_TEXT_MAX_LENGTH = 2e3;
|
|
10225
10266
|
var TemplatePortBaseFields = {
|
|
10226
10267
|
/** Stable handle id on the box, e.g. "in_character", "out_angle_1". */
|
|
10227
10268
|
id: external_exports.string(),
|
|
@@ -10238,7 +10279,25 @@ var TemplatePortBaseFields = {
|
|
|
10238
10279
|
*/
|
|
10239
10280
|
internalHandle: external_exports.string().nullable(),
|
|
10240
10281
|
/** Optional vertical position override on the box (e.g. "35%"). */
|
|
10241
|
-
top: external_exports.string().optional()
|
|
10282
|
+
top: external_exports.string().optional(),
|
|
10283
|
+
/**
|
|
10284
|
+
* Example media for a MEDIA port (image/video/audio input source or output
|
|
10285
|
+
* result), shown in the template details panel and the build/edit authoring
|
|
10286
|
+
* UIs. `exampleAssetKey` is the persisted ref: an S3 object key under
|
|
10287
|
+
* `template-examples/`, copied at capture so the example outlives the source
|
|
10288
|
+
* canvas — exactly like `previewImageUrl`. `exampleAssetUrl` is the
|
|
10289
|
+
* freshly-signed display URL, populated on read only and ignored on write.
|
|
10290
|
+
* Both absent when the port has no media example (unset, or a text port).
|
|
10291
|
+
*/
|
|
10292
|
+
exampleAssetKey: external_exports.string().nullable().optional(),
|
|
10293
|
+
exampleAssetUrl: external_exports.string().nullable().optional(),
|
|
10294
|
+
/**
|
|
10295
|
+
* Example prompt for a TEXT port — the text parallel of `exampleAssetKey`.
|
|
10296
|
+
* Stored inline (no S3, no signing) since it's just a string; the details
|
|
10297
|
+
* panel shows it truncated, and "use example as input" drops a text node
|
|
10298
|
+
* pre-filled with it. Absent for media ports and text ports with no example.
|
|
10299
|
+
*/
|
|
10300
|
+
exampleText: external_exports.string().max(TEMPLATE_EXAMPLE_TEXT_MAX_LENGTH).nullable().optional()
|
|
10242
10301
|
};
|
|
10243
10302
|
var TemplatePortTargetSchema = external_exports.object({
|
|
10244
10303
|
nodeKey: external_exports.string(),
|
|
@@ -10336,15 +10395,6 @@ var InstancePortBindingSchema = external_exports.discriminatedUnion("direction",
|
|
|
10336
10395
|
...InstancePortBindingBaseFields
|
|
10337
10396
|
})
|
|
10338
10397
|
]);
|
|
10339
|
-
var TemplatePortSummarySchema = external_exports.object({
|
|
10340
|
-
id: external_exports.string(),
|
|
10341
|
-
direction: external_exports.enum(["input", "output"]),
|
|
10342
|
-
label: external_exports.string(),
|
|
10343
|
-
handleType: external_exports.string(),
|
|
10344
|
-
required: external_exports.boolean().optional(),
|
|
10345
|
-
maxConnections: external_exports.number().int().positive().optional(),
|
|
10346
|
-
outputAspectRatio: external_exports.enum(ASPECT_RATIOS).nullable().optional()
|
|
10347
|
-
});
|
|
10348
10398
|
|
|
10349
10399
|
// ../api-contract/src/canvas.ts
|
|
10350
10400
|
var c7 = initContract();
|
|
@@ -11286,7 +11336,33 @@ var CanvasSettingsResponseSchema = external_exports.object({
|
|
|
11286
11336
|
createdAt: external_exports.string().datetime(),
|
|
11287
11337
|
updatedAt: external_exports.string().datetime()
|
|
11288
11338
|
});
|
|
11339
|
+
var PlaygroundCanvasReferenceSchema = external_exports.object({
|
|
11340
|
+
projectId: external_exports.string().uuid(),
|
|
11341
|
+
canvasId: external_exports.string().uuid()
|
|
11342
|
+
});
|
|
11343
|
+
var PlaygroundCanvasPageSchema = external_exports.object({
|
|
11344
|
+
projectId: external_exports.string().uuid().nullable(),
|
|
11345
|
+
data: external_exports.array(external_exports.object({ id: external_exports.string().uuid() })),
|
|
11346
|
+
total: external_exports.number().int().nonnegative()
|
|
11347
|
+
});
|
|
11289
11348
|
var canvasContract = c7.router({
|
|
11349
|
+
createPlaygroundCanvas: {
|
|
11350
|
+
method: "POST",
|
|
11351
|
+
path: "/playground/canvases",
|
|
11352
|
+
body: null,
|
|
11353
|
+
responses: {
|
|
11354
|
+
201: PlaygroundCanvasReferenceSchema,
|
|
11355
|
+
409: MessageResponseSchema
|
|
11356
|
+
}
|
|
11357
|
+
},
|
|
11358
|
+
listPlaygroundCanvases: {
|
|
11359
|
+
method: "GET",
|
|
11360
|
+
path: "/playground/canvases",
|
|
11361
|
+
query: external_exports.object({
|
|
11362
|
+
...paginationQuery({ maxLimit: 100, defaultLimit: 25 })
|
|
11363
|
+
}),
|
|
11364
|
+
responses: { 200: PlaygroundCanvasPageSchema }
|
|
11365
|
+
},
|
|
11290
11366
|
createCanvas: {
|
|
11291
11367
|
method: "POST",
|
|
11292
11368
|
path: "/projects/:projectId/canvases",
|
|
@@ -12960,6 +13036,10 @@ var ProfileUserSchema = external_exports.object({
|
|
|
12960
13036
|
name: external_exports.string(),
|
|
12961
13037
|
email: external_exports.string(),
|
|
12962
13038
|
agentAutoRun: external_exports.boolean(),
|
|
13039
|
+
// Set once the user answers the "how did you hear about us" intro. Marks
|
|
13040
|
+
// the account-level onboarding as done, independently of the canvas
|
|
13041
|
+
// product tour (`completedProductTour`).
|
|
13042
|
+
signupSource: external_exports.string().nullable(),
|
|
12963
13043
|
completedProductTour: external_exports.string().datetime().nullable(),
|
|
12964
13044
|
avatarUrl: external_exports.string().nullable(),
|
|
12965
13045
|
advancedSettings: UserAdvancedSettingsSchema
|
|
@@ -13816,8 +13896,81 @@ var projectContract = c14.router({
|
|
|
13816
13896
|
}
|
|
13817
13897
|
});
|
|
13818
13898
|
|
|
13899
|
+
// ../api-contract/src/template-apply-input.ts
|
|
13900
|
+
var TemplateApplyInputSchema = external_exports.discriminatedUnion("kind", [
|
|
13901
|
+
external_exports.object({
|
|
13902
|
+
kind: external_exports.literal("asset"),
|
|
13903
|
+
portId: external_exports.string(),
|
|
13904
|
+
assetId: external_exports.string().uuid(),
|
|
13905
|
+
mediaType: external_exports.enum(["image", "video", "audio", "pdf"])
|
|
13906
|
+
}),
|
|
13907
|
+
external_exports.object({
|
|
13908
|
+
kind: external_exports.literal("text"),
|
|
13909
|
+
portId: external_exports.string(),
|
|
13910
|
+
text: external_exports.string().min(1)
|
|
13911
|
+
})
|
|
13912
|
+
]);
|
|
13913
|
+
|
|
13914
|
+
// ../api-contract/src/template-public-api.ts
|
|
13915
|
+
var TemplateResponseSchema = external_exports.object({
|
|
13916
|
+
id: external_exports.string(),
|
|
13917
|
+
title: external_exports.string(),
|
|
13918
|
+
groupLabel: external_exports.string(),
|
|
13919
|
+
icon: external_exports.string(),
|
|
13920
|
+
description: external_exports.string(),
|
|
13921
|
+
previewImageUrl: external_exports.string().nullable(),
|
|
13922
|
+
previewVideoUrl: external_exports.string().nullable().optional(),
|
|
13923
|
+
inputPorts: external_exports.array(TemplatePortSummarySchema),
|
|
13924
|
+
outputPorts: external_exports.array(TemplatePortSummarySchema),
|
|
13925
|
+
canEdit: external_exports.boolean(),
|
|
13926
|
+
isGlobal: external_exports.boolean().optional(),
|
|
13927
|
+
authorName: external_exports.string().nullable().optional(),
|
|
13928
|
+
estimatedCreditCost: external_exports.number().optional(),
|
|
13929
|
+
tags: external_exports.array(external_exports.string()).optional()
|
|
13930
|
+
});
|
|
13931
|
+
var PublicApplyTemplateResponseSchema = external_exports.object({
|
|
13932
|
+
/** The created template instance id. */
|
|
13933
|
+
instanceId: external_exports.string(),
|
|
13934
|
+
/** The collapsed group id shown on the canvas. */
|
|
13935
|
+
groupId: external_exports.string()
|
|
13936
|
+
});
|
|
13937
|
+
var ApplyTemplateBodySchema = external_exports.object({
|
|
13938
|
+
canvasId: external_exports.string().uuid(),
|
|
13939
|
+
templateId: external_exports.string().uuid(),
|
|
13940
|
+
/** Box center X. Auto-positioned to avoid existing nodes if omitted. */
|
|
13941
|
+
centerX: external_exports.number().optional(),
|
|
13942
|
+
/** Box center Y. Auto-positioned to avoid existing nodes if omitted. */
|
|
13943
|
+
centerY: external_exports.number().optional(),
|
|
13944
|
+
/** Optional input values materialized with the template instance. */
|
|
13945
|
+
inputs: external_exports.array(TemplateApplyInputSchema).optional()
|
|
13946
|
+
});
|
|
13947
|
+
var templateListRoute = {
|
|
13948
|
+
method: "GET",
|
|
13949
|
+
path: "/templates",
|
|
13950
|
+
responses: {
|
|
13951
|
+
200: external_exports.object({
|
|
13952
|
+
data: external_exports.array(TemplateResponseSchema)
|
|
13953
|
+
})
|
|
13954
|
+
},
|
|
13955
|
+
summary: "List available templates (active)"
|
|
13956
|
+
};
|
|
13957
|
+
var templateApplyRouteBase = {
|
|
13958
|
+
method: "POST",
|
|
13959
|
+
path: "/templates/apply",
|
|
13960
|
+
body: ApplyTemplateBodySchema,
|
|
13961
|
+
summary: "Apply a template as a collapsed canvas box"
|
|
13962
|
+
};
|
|
13963
|
+
var publicTemplateApplyRoute = {
|
|
13964
|
+
...templateApplyRouteBase,
|
|
13965
|
+
responses: {
|
|
13966
|
+
200: PublicApplyTemplateResponseSchema,
|
|
13967
|
+
404: MessageResponseSchema
|
|
13968
|
+
}
|
|
13969
|
+
};
|
|
13970
|
+
|
|
13819
13971
|
// ../api-contract/src/upload.ts
|
|
13820
13972
|
var c15 = initContract();
|
|
13973
|
+
var PdfExtractionModeSchema = external_exports.enum(["summary", "pages"]);
|
|
13821
13974
|
var InitUploadBodySchema = external_exports.object({
|
|
13822
13975
|
nodeId: external_exports.string().uuid().optional(),
|
|
13823
13976
|
filename: external_exports.string(),
|
|
@@ -13877,7 +14030,10 @@ var CompleteUploadBodySchema = external_exports.object({
|
|
|
13877
14030
|
// edit/upstream change to keep `src` fresh for downstream nodes; those
|
|
13878
14031
|
// background refreshes set this so they don't mint a new version each time.
|
|
13879
14032
|
// Explicit user saves omit it and fork a new version as usual.
|
|
13880
|
-
replaceActiveVersion: external_exports.boolean().optional()
|
|
14033
|
+
replaceActiveVersion: external_exports.boolean().optional(),
|
|
14034
|
+
// PDF-only: how to process the upload once complete. Omitted ⇒ "summary"
|
|
14035
|
+
// (the server default and every non-PDF upload). See PdfExtractionModeSchema.
|
|
14036
|
+
pdfExtractionMode: PdfExtractionModeSchema.optional()
|
|
13881
14037
|
});
|
|
13882
14038
|
var CompleteUploadResponseSchema = external_exports.object({
|
|
13883
14039
|
success: external_exports.boolean(),
|
|
@@ -13998,6 +14154,10 @@ var publicContract = c16.router(
|
|
|
13998
14154
|
preset: {
|
|
13999
14155
|
list: presetsContract.listPresets
|
|
14000
14156
|
},
|
|
14157
|
+
template: {
|
|
14158
|
+
list: templateListRoute,
|
|
14159
|
+
apply: publicTemplateApplyRoute
|
|
14160
|
+
},
|
|
14001
14161
|
team: {
|
|
14002
14162
|
list: teamContract.listMyTeams
|
|
14003
14163
|
},
|
|
@@ -14249,7 +14409,7 @@ function isMajorUpgrade(current, latest) {
|
|
|
14249
14409
|
return l[0] > c17[0];
|
|
14250
14410
|
}
|
|
14251
14411
|
function shouldShowUpgradeNotice(ctx = {}) {
|
|
14252
|
-
const current = ctx.current ?? "0.
|
|
14412
|
+
const current = ctx.current ?? "0.10.1";
|
|
14253
14413
|
const latest = ctx.latest ?? serverLatestVersion;
|
|
14254
14414
|
const env = ctx.env ?? process.env;
|
|
14255
14415
|
const isTty = ctx.isTty ?? Boolean(process.stderr.isTTY);
|
|
@@ -14270,7 +14430,7 @@ Upgrade: npm install -g @melius-ai/cli@latest (or: brew update && brew upgrade
|
|
|
14270
14430
|
function printUpgradeNoticeIfNeeded(ctx = {}) {
|
|
14271
14431
|
try {
|
|
14272
14432
|
if (!shouldShowUpgradeNotice(ctx)) return;
|
|
14273
|
-
const current = ctx.current ?? "0.
|
|
14433
|
+
const current = ctx.current ?? "0.10.1";
|
|
14274
14434
|
const latest = ctx.latest ?? serverLatestVersion;
|
|
14275
14435
|
process.stderr.write(formatUpgradeNotice(current, latest));
|
|
14276
14436
|
} catch {
|
|
@@ -15302,14 +15462,27 @@ function shiftToAvoidExisting(result, allNodes, targetIds, allEdges = []) {
|
|
|
15302
15462
|
}));
|
|
15303
15463
|
const existingIds = new Set(otherNodes.map((n) => n.id));
|
|
15304
15464
|
const nodeById = new Map(allNodes.map((n) => [n.id, n]));
|
|
15465
|
+
function resolveTopLevelNodeId(id) {
|
|
15466
|
+
let resolvedId = id;
|
|
15467
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15468
|
+
while (!seen.has(resolvedId)) {
|
|
15469
|
+
seen.add(resolvedId);
|
|
15470
|
+
const parentId2 = nodeById.get(resolvedId)?.groupId;
|
|
15471
|
+
if (!parentId2) break;
|
|
15472
|
+
resolvedId = parentId2;
|
|
15473
|
+
}
|
|
15474
|
+
return resolvedId;
|
|
15475
|
+
}
|
|
15305
15476
|
const incomingSourceIds = /* @__PURE__ */ new Set();
|
|
15306
15477
|
const outgoingTargetIds = /* @__PURE__ */ new Set();
|
|
15307
15478
|
for (const edge of allEdges) {
|
|
15308
|
-
|
|
15309
|
-
|
|
15479
|
+
const srcNodeId = resolveTopLevelNodeId(edge.srcNodeId);
|
|
15480
|
+
const dstNodeId = resolveTopLevelNodeId(edge.dstNodeId);
|
|
15481
|
+
if (existingIds.has(srcNodeId) && targetIds.has(dstNodeId)) {
|
|
15482
|
+
incomingSourceIds.add(srcNodeId);
|
|
15310
15483
|
}
|
|
15311
|
-
if (targetIds.has(
|
|
15312
|
-
outgoingTargetIds.add(
|
|
15484
|
+
if (targetIds.has(srcNodeId) && existingIds.has(dstNodeId)) {
|
|
15485
|
+
outgoingTargetIds.add(dstNodeId);
|
|
15313
15486
|
}
|
|
15314
15487
|
}
|
|
15315
15488
|
const SCATTER_THRESHOLD = 3;
|
|
@@ -15702,6 +15875,11 @@ function resolveNodeIds(lookup, nodeIds) {
|
|
|
15702
15875
|
return { resolvedNodeIds, unresolvedTempLabels };
|
|
15703
15876
|
}
|
|
15704
15877
|
|
|
15878
|
+
// ../api-contract/src/edge-id.ts
|
|
15879
|
+
function normalizeEdgeId(id, generateId = () => crypto.randomUUID()) {
|
|
15880
|
+
return id && UUID_RE.test(id) ? id : generateId();
|
|
15881
|
+
}
|
|
15882
|
+
|
|
15705
15883
|
// ../api-contract/src/media-types.ts
|
|
15706
15884
|
var IMAGE_CONTENT_TYPE_BY_EXTENSION = {
|
|
15707
15885
|
".jpg": "image/jpeg",
|
|
@@ -16932,7 +17110,7 @@ Valid node types: text, image, video, audio, file, group, custom_text, stitch.
|
|
|
16932
17110
|
if (edgeItems && edgeItems.length > 0) {
|
|
16933
17111
|
const resolveId = (ref) => labelToId.get(ref) ?? ref;
|
|
16934
17112
|
const edges = edgeItems.map((item) => ({
|
|
16935
|
-
id: item.id
|
|
17113
|
+
id: normalizeEdgeId(item.id),
|
|
16936
17114
|
srcNodeId: resolveId(item.src),
|
|
16937
17115
|
dstNodeId: resolveId(item.dst),
|
|
16938
17116
|
edgeType: item.type,
|
|
@@ -18816,6 +18994,120 @@ Examples:
|
|
|
18816
18994
|
);
|
|
18817
18995
|
}
|
|
18818
18996
|
|
|
18997
|
+
// src/commands/template.ts
|
|
18998
|
+
function parseCoordinate(value, option) {
|
|
18999
|
+
if (value === void 0) return void 0;
|
|
19000
|
+
const parsed = Number(value);
|
|
19001
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
19002
|
+
writeError(
|
|
19003
|
+
formatError("USAGE_ERROR", `${option} must be a finite number`, {
|
|
19004
|
+
suggestion: `Provide ${option} <number> or omit it for automatic placement`
|
|
19005
|
+
}),
|
|
19006
|
+
EXIT_USAGE_ERROR
|
|
19007
|
+
);
|
|
19008
|
+
}
|
|
19009
|
+
function parseInputs(value) {
|
|
19010
|
+
if (value === void 0) return void 0;
|
|
19011
|
+
let parsed;
|
|
19012
|
+
try {
|
|
19013
|
+
parsed = JSON.parse(value);
|
|
19014
|
+
} catch {
|
|
19015
|
+
writeError(
|
|
19016
|
+
formatError("USAGE_ERROR", "Invalid JSON in --inputs", {
|
|
19017
|
+
suggestion: `--inputs must be a JSON array, for example '[{"kind":"text","portId":"prompt","text":"A red shoe"}]'`
|
|
19018
|
+
}),
|
|
19019
|
+
EXIT_USAGE_ERROR
|
|
19020
|
+
);
|
|
19021
|
+
}
|
|
19022
|
+
const result = TemplateApplyInputSchema.array().safeParse(parsed);
|
|
19023
|
+
if (result.success) return result.data;
|
|
19024
|
+
writeError(
|
|
19025
|
+
formatError(
|
|
19026
|
+
"USAGE_ERROR",
|
|
19027
|
+
result.error.issues.map((issue) => issue.message).join("; "),
|
|
19028
|
+
{
|
|
19029
|
+
suggestion: 'Use text inputs {"kind":"text","portId":"<portId>","text":"<text>"} or asset inputs {"kind":"asset","portId":"<portId>","assetId":"<assetId>","mediaType":"image|video|audio|pdf"}'
|
|
19030
|
+
}
|
|
19031
|
+
),
|
|
19032
|
+
EXIT_USAGE_ERROR
|
|
19033
|
+
);
|
|
19034
|
+
}
|
|
19035
|
+
function registerTemplateCommands(program2, getOutputOpts) {
|
|
19036
|
+
const template = program2.command("template").description("List and apply opaque canvas workflow templates");
|
|
19037
|
+
template.command("list").description(
|
|
19038
|
+
"List available templates with display metadata and declared input/output ports"
|
|
19039
|
+
).addHelpText(
|
|
19040
|
+
"after",
|
|
19041
|
+
`
|
|
19042
|
+
Returns: Array of templates with id, title, description, previewImageUrl, inputPorts, outputPorts, and estimatedCreditCost.
|
|
19043
|
+
Includes global templates and templates scoped to the current team.
|
|
19044
|
+
The template's internal workflow stays private. Use a returned id with mel template apply.
|
|
19045
|
+
|
|
19046
|
+
Examples:
|
|
19047
|
+
$ mel template list
|
|
19048
|
+
$ mel template list --fields id,title,inputPorts,outputPorts`
|
|
19049
|
+
).action(async () => {
|
|
19050
|
+
const client = getClient();
|
|
19051
|
+
const result = await client.template.list();
|
|
19052
|
+
if (result.status !== 200) {
|
|
19053
|
+
handleApiError(result.status, result.body);
|
|
19054
|
+
}
|
|
19055
|
+
writeJson(result.body.data, getOutputOpts());
|
|
19056
|
+
});
|
|
19057
|
+
template.command("apply").description(
|
|
19058
|
+
"Apply a template to a canvas as one collapsed box and return its instanceId and groupId"
|
|
19059
|
+
).argument(
|
|
19060
|
+
"<canvasId>",
|
|
19061
|
+
"Canvas ID (from mel canvas create or mel canvas list output)"
|
|
19062
|
+
).argument("<templateId>", "Template ID (from mel template list output)").option(
|
|
19063
|
+
"--center-x <number>",
|
|
19064
|
+
"X center for the template box. Omit for automatic non-overlapping placement"
|
|
19065
|
+
).option(
|
|
19066
|
+
"--center-y <number>",
|
|
19067
|
+
"Y center for the template box. Omit for automatic non-overlapping placement"
|
|
19068
|
+
).option(
|
|
19069
|
+
"--inputs <json>",
|
|
19070
|
+
"JSON array of text or library-asset inputs targeting port IDs from mel template list"
|
|
19071
|
+
).addHelpText(
|
|
19072
|
+
"after",
|
|
19073
|
+
`
|
|
19074
|
+
Returns: { instanceId, groupId }. Internal workflow node IDs are never returned.
|
|
19075
|
+
Input kinds: text {kind,portId,text}; asset {kind,portId,assetId,mediaType} where mediaType is image, video, audio, or pdf.
|
|
19076
|
+
Omit --center-x/--center-y to place the box automatically. Use mel canvas content <canvasId> afterward to inspect its public ports.
|
|
19077
|
+
Run the applied template with mel bulk-run start <canvasId> --node-ids <groupId> --wait.
|
|
19078
|
+
|
|
19079
|
+
Examples:
|
|
19080
|
+
$ mel template apply <canvasId> <templateId>
|
|
19081
|
+
$ mel template apply <canvasId> <templateId> --inputs '[{"kind":"text","portId":"<portId>","text":"A red shoe"}]'
|
|
19082
|
+
$ mel bulk-run start <canvasId> --node-ids <groupId> --wait`
|
|
19083
|
+
).action(
|
|
19084
|
+
async (canvasId, templateId, opts) => {
|
|
19085
|
+
const client = getClient();
|
|
19086
|
+
const centerX = parseCoordinate(opts.centerX, "--center-x");
|
|
19087
|
+
const centerY = parseCoordinate(opts.centerY, "--center-y");
|
|
19088
|
+
const inputs = parseInputs(opts.inputs);
|
|
19089
|
+
const result = await client.template.apply({
|
|
19090
|
+
body: {
|
|
19091
|
+
canvasId,
|
|
19092
|
+
templateId,
|
|
19093
|
+
...centerX !== void 0 && { centerX },
|
|
19094
|
+
...centerY !== void 0 && { centerY },
|
|
19095
|
+
...inputs !== void 0 && { inputs }
|
|
19096
|
+
}
|
|
19097
|
+
});
|
|
19098
|
+
if (result.status !== 200) {
|
|
19099
|
+
handleApiError(
|
|
19100
|
+
result.status,
|
|
19101
|
+
result.body,
|
|
19102
|
+
"Run: mel template list"
|
|
19103
|
+
);
|
|
19104
|
+
}
|
|
19105
|
+
const { instanceId, groupId } = result.body;
|
|
19106
|
+
writeJson({ instanceId, groupId }, getOutputOpts());
|
|
19107
|
+
}
|
|
19108
|
+
);
|
|
19109
|
+
}
|
|
19110
|
+
|
|
18819
19111
|
// src/lib/upload.ts
|
|
18820
19112
|
import * as fs3 from "fs";
|
|
18821
19113
|
import * as path3 from "path";
|
|
@@ -19271,7 +19563,7 @@ function withDefaultHelp(args) {
|
|
|
19271
19563
|
}
|
|
19272
19564
|
function createProgram() {
|
|
19273
19565
|
const program2 = new Command();
|
|
19274
|
-
program2.name("mel").description("Mel \u2014 Melius agent CLI").version("0.
|
|
19566
|
+
program2.name("mel").description("Mel \u2014 Melius agent CLI").version("0.10.1").showSuggestionAfterError(true).option("--json", "Force JSON output (default)").option("--text", "Human-readable output").option(
|
|
19275
19567
|
"--fields <fields>",
|
|
19276
19568
|
"Select specific output fields (comma-separated)"
|
|
19277
19569
|
).option("--quiet", "Suppress output, exit code only").option("--verbose", "Log request/response metadata to stderr").addHelpText(
|
|
@@ -19310,6 +19602,7 @@ Learn more: https://docs.melius.com`
|
|
|
19310
19602
|
registerAudioCommands(program2, getOutputOpts);
|
|
19311
19603
|
registerFontCommands(program2, getOutputOpts);
|
|
19312
19604
|
registerPresetCommands(program2, getOutputOpts);
|
|
19605
|
+
registerTemplateCommands(program2, getOutputOpts);
|
|
19313
19606
|
registerConfigCommands(program2, getOutputOpts);
|
|
19314
19607
|
if (false) {
|
|
19315
19608
|
registerSkillCommands(program2, getOutputOpts);
|
package/dist/src/index.js
CHANGED