@melius-ai/cli 0.6.0 → 0.7.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/README.md +9 -1
- package/dist/bin/mel.js +1 -1
- package/dist/{chunk-EN744KKV.js → chunk-5QT6WMID.js} +110 -18
- package/dist/src/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -261,17 +261,25 @@ Requires the Pro or Enterprise plan.
|
|
|
261
261
|
|
|
262
262
|
| Command | Description |
|
|
263
263
|
| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
264
|
-
| `mel asset search
|
|
264
|
+
| `mel asset search [query]` | Search the team's Files/DAM library (uploads + past generations) by meaning; exact matches rank first. Returns up to 20 matches per page |
|
|
265
|
+
| `mel asset folders` | List the library's folders (`id`, `name`, `path`, `fileCount`) so you can resolve a folder name to an id for `--folder-id` |
|
|
265
266
|
| `mel asset place <canvasId> <assetIds...>` | Place existing library assets onto a canvas by id — references the **original** asset (no duplicate) |
|
|
266
267
|
|
|
267
268
|
`mel asset search` searches by meaning (semantic), with exact filename/title matches ranked first, so query with a filename or a description of the content. It returns `{ query, total, results: [{ assetId, filename, fileType, previewUrl, ... }] }`. Filter with `--file-type <image|video|audio|pdf|text>` and `--limit <1-20>`; page deeper with `--offset <n>` (skip the first N matches — page until the running count reaches `total`); scope to one canvas with `--canvas-id` (omit to search the whole team library).
|
|
268
269
|
|
|
270
|
+
Scope to a **folder** with `--folder-id` (from `mel asset folders`): with a query it filters within that folder and its subfolders; **omit the query** to bring in the _whole_ folder (every asset in it). `mel asset folders` returns each folder's root-relative `path` (e.g. `Brand / Logos`) to disambiguate same-named folders.
|
|
271
|
+
|
|
269
272
|
`mel asset place` creates a file node per asset (writes to CRDT, no re-upload) and returns `{ placed: [{ assetId, nodeId, mediaType }] }`. Wire the returned `nodeId`s into generations with `mel edge create`. This is the correct way to reuse an existing library asset — do **not** re-upload it.
|
|
270
273
|
|
|
271
274
|
```bash
|
|
272
275
|
# Find an asset, then bring it onto a canvas and wire it
|
|
273
276
|
mel asset search "black jacket shot" --file-type image
|
|
274
277
|
mel asset place <canvasId> <assetId1> <assetId2>
|
|
278
|
+
|
|
279
|
+
# Bring in a whole folder: resolve the folder, then search it with no query
|
|
280
|
+
mel asset folders # → [{ id, name, path, fileCount }]
|
|
281
|
+
mel asset search --folder-id <folderId> # every asset in the folder
|
|
282
|
+
mel asset search "shark" --folder-id <folderId> # or filter within it
|
|
275
283
|
```
|
|
276
284
|
|
|
277
285
|
### Shell completion
|
package/dist/bin/mel.js
CHANGED
|
@@ -8085,13 +8085,18 @@ var ListFilesResponseSchema = external_exports.object({
|
|
|
8085
8085
|
});
|
|
8086
8086
|
var AGENT_ASSET_SEARCH_PAGE_SIZE = 20;
|
|
8087
8087
|
var AgentAssetSearchQuerySchema = external_exports.object({
|
|
8088
|
-
query: external_exports.string().trim().min(1).max(500).describe(
|
|
8088
|
+
query: external_exports.string().trim().min(1).max(500).optional().describe(
|
|
8089
|
+
'The semantic search query \u2014 a filename or a description of the asset (e.g. "red logo", "the shark photo"). Provide it to FIND specific assets. OMIT it entirely to bring in EVERY asset from a folder: when the member says "bring in all my assets from the X folder" / "add everything in X to the canvas", resolve the folder with list_asset_folders and call asset_search with just that `folderId` and NO query. Never invent a query when the member asked for everything in a folder \u2014 a query filters and will drop assets they wanted. Omitting the query requires a `folderId`.'
|
|
8090
|
+
),
|
|
8089
8091
|
limit: external_exports.coerce.number().int().min(1).max(AGENT_ASSET_SEARCH_PAGE_SIZE).default(AGENT_ASSET_SEARCH_PAGE_SIZE),
|
|
8090
8092
|
source: FileSourceSchema.optional(),
|
|
8091
8093
|
fileType: FileTypeSchema.optional(),
|
|
8092
8094
|
canvasId: external_exports.string().uuid().optional().describe(
|
|
8093
8095
|
'Optional. Omit to search the whole team library \u2014 this is the default and what nearly every request wants (e.g. "use the asset I have"). Only set this to scope to a DIFFERENT canvas the member explicitly names ("search my other canvas"), resolving the id from canvas_list. Do NOT pass the canvas the chat is currently on (its assets are already visible via canvas_content, and scoping there hides whole-library matches), and never guess an id.'
|
|
8094
8096
|
),
|
|
8097
|
+
folderId: external_exports.string().uuid().optional().describe(
|
|
8098
|
+
'Optional. Scope to one Files folder AND its subfolders. Omit to search the whole team library \u2014 the default, and what nearly every request wants. Set it when the member names a specific folder \u2014 either to FILTER within it (pass `folderId` + `query`, e.g. "find the shark shot in my ocean folder") or to bring in EVERYTHING in it (pass `folderId` and OMIT `query`, e.g. "add all my assets from the ocean folder"). Resolve the id with list_asset_folders (match by name; if several plausibly match, ask which one); never guess a folder id.'
|
|
8099
|
+
),
|
|
8095
8100
|
showInThread: external_exports.boolean().optional().describe(
|
|
8096
8101
|
'Slack only. Set true when the member only wants to SEE the matched asset(s) \u2014 "find X and show it to me", "do I have Y?" \u2014 and is NOT asking to place, edit, or build on them. Skips the selection card and posts every match straight into the Slack thread as image files. Leave unset (the default) whenever the member wants to USE an asset on the canvas, so the selection card renders and a canvas gets bound.'
|
|
8097
8102
|
)
|
|
@@ -8112,7 +8117,27 @@ var AgentAssetSearchRequestSchema = AgentAssetSearchQuerySchema.extend(
|
|
|
8112
8117
|
var AgentAssetSearchResponseSchema = external_exports.object({
|
|
8113
8118
|
query: external_exports.string(),
|
|
8114
8119
|
results: external_exports.array(FileCardSchema),
|
|
8115
|
-
total: external_exports.number().int().nonnegative()
|
|
8120
|
+
total: external_exports.number().int().nonnegative(),
|
|
8121
|
+
// Echo the search scope so the picker's "More results" button can re-page
|
|
8122
|
+
// with the SAME scope. Without this, page 2 drops the folder/canvas filter
|
|
8123
|
+
// and pages the whole library (and a query-less folder browse can't page at
|
|
8124
|
+
// all). Absent when the corresponding filter wasn't set.
|
|
8125
|
+
folderId: external_exports.string().uuid().optional(),
|
|
8126
|
+
canvasId: external_exports.string().uuid().optional(),
|
|
8127
|
+
source: FileSourceSchema.optional(),
|
|
8128
|
+
fileType: FileTypeSchema.optional()
|
|
8129
|
+
});
|
|
8130
|
+
var AgentListAssetFoldersQuerySchema = external_exports.object({});
|
|
8131
|
+
var AgentAssetFolderSchema = external_exports.object({
|
|
8132
|
+
id: external_exports.string().uuid(),
|
|
8133
|
+
name: external_exports.string(),
|
|
8134
|
+
// Full path from the team root (e.g. "Brand / Logos") so the agent can
|
|
8135
|
+
// disambiguate when several folders share a name.
|
|
8136
|
+
path: external_exports.string(),
|
|
8137
|
+
fileCount: external_exports.number().int().nonnegative()
|
|
8138
|
+
});
|
|
8139
|
+
var AgentListAssetFoldersResponseSchema = external_exports.object({
|
|
8140
|
+
folders: external_exports.array(AgentAssetFolderSchema)
|
|
8116
8141
|
});
|
|
8117
8142
|
var InitFilesUploadBodySchema = external_exports.object({
|
|
8118
8143
|
filename: external_exports.string(),
|
|
@@ -8290,6 +8315,15 @@ var filesContract = c2.router({
|
|
|
8290
8315
|
},
|
|
8291
8316
|
summary: "Search team assets for the agent"
|
|
8292
8317
|
},
|
|
8318
|
+
listAgentAssetFolders: {
|
|
8319
|
+
method: "GET",
|
|
8320
|
+
path: "/files/agent-folders",
|
|
8321
|
+
responses: {
|
|
8322
|
+
200: AgentListAssetFoldersResponseSchema,
|
|
8323
|
+
403: ErrorBodySchema
|
|
8324
|
+
},
|
|
8325
|
+
summary: "List team asset folders for the agent"
|
|
8326
|
+
},
|
|
8293
8327
|
getEmbeddingStorageUsage: {
|
|
8294
8328
|
method: "GET",
|
|
8295
8329
|
path: "/files/embedding-storage-usage",
|
|
@@ -10165,9 +10199,10 @@ var CropRectSchema = external_exports.object({
|
|
|
10165
10199
|
});
|
|
10166
10200
|
var StitchClipOrderSchema = external_exports.array(external_exports.string());
|
|
10167
10201
|
var StitchScaleFitSchema = external_exports.enum(["fit", "stretch"]);
|
|
10202
|
+
var roundMs = (value) => typeof value === "number" ? Math.round(value) : value;
|
|
10168
10203
|
var StitchTrimWindowFields = {
|
|
10169
|
-
trimStartMs: external_exports.number().int().nonnegative().optional(),
|
|
10170
|
-
trimEndMs: external_exports.number().int().positive().optional()
|
|
10204
|
+
trimStartMs: external_exports.preprocess(roundMs, external_exports.number().int().nonnegative()).optional(),
|
|
10205
|
+
trimEndMs: external_exports.preprocess(roundMs, external_exports.number().int().positive()).optional()
|
|
10171
10206
|
};
|
|
10172
10207
|
var StitchAudioOverlaySchema = external_exports.object({
|
|
10173
10208
|
nodeId: external_exports.string(),
|
|
@@ -12202,6 +12237,10 @@ var ModelCostSchema = external_exports.discriminatedUnion("type", [
|
|
|
12202
12237
|
maxCreditCost: external_exports.number()
|
|
12203
12238
|
})
|
|
12204
12239
|
]);
|
|
12240
|
+
var TextTokenPricingSchema = external_exports.object({
|
|
12241
|
+
inputCreditsPerMillionTokens: external_exports.number(),
|
|
12242
|
+
outputCreditsPerMillionTokens: external_exports.number()
|
|
12243
|
+
});
|
|
12205
12244
|
var InputFileSizeConstraintsResponseSchema = external_exports.object({
|
|
12206
12245
|
maximumFileBytes: external_exports.number().int().nonnegative().optional(),
|
|
12207
12246
|
maximumTotalBytes: external_exports.number().int().nonnegative().optional()
|
|
@@ -12307,7 +12346,9 @@ var ModelResponseSchema = external_exports.object({
|
|
|
12307
12346
|
hiddenFromAgent: external_exports.boolean().optional(),
|
|
12308
12347
|
promoRateLimit: PromoRateLimitSchema.optional(),
|
|
12309
12348
|
/** Maximum prompt length in characters. Used by text models that lack variants. */
|
|
12310
|
-
maxPromptLength: external_exports.number().nullable().optional()
|
|
12349
|
+
maxPromptLength: external_exports.number().nullable().optional(),
|
|
12350
|
+
/** Per-1M-token credit rates for text models; drives the live cost-range estimate. */
|
|
12351
|
+
textTokenPricing: TextTokenPricingSchema.optional()
|
|
12311
12352
|
});
|
|
12312
12353
|
var ListGenerativeModelsResponseSchema = external_exports.object({
|
|
12313
12354
|
models: external_exports.array(ModelResponseSchema)
|
|
@@ -12800,7 +12841,8 @@ var EnterpriseOrderLineItemSchema = external_exports.object({
|
|
|
12800
12841
|
var EnterpriseBillingIntervalSchema = external_exports.enum(["monthly", "annual"]);
|
|
12801
12842
|
var EnterpriseStripeBillingInputSchema = external_exports.object({
|
|
12802
12843
|
unitAmount: external_exports.number().int().positive(),
|
|
12803
|
-
|
|
12844
|
+
// Expose the transform output to OpenAPI generation.
|
|
12845
|
+
currency: external_exports.string().length(3).transform((value) => value.toLowerCase()).pipe(external_exports.string()),
|
|
12804
12846
|
billingInterval: EnterpriseBillingIntervalSchema,
|
|
12805
12847
|
creditsPerPeriod: external_exports.number().int().positive(),
|
|
12806
12848
|
contractEndAt: external_exports.string().datetime().optional()
|
|
@@ -12864,7 +12906,8 @@ var EnterprisePendingExpansionSchema = external_exports.object({
|
|
|
12864
12906
|
});
|
|
12865
12907
|
var EnterpriseStripeBillingSchema = external_exports.object({
|
|
12866
12908
|
unitAmount: external_exports.number().int().positive(),
|
|
12867
|
-
|
|
12909
|
+
// Expose the transform output to OpenAPI generation.
|
|
12910
|
+
currency: external_exports.string().length(3).transform((value) => value.toLowerCase()).pipe(external_exports.string()),
|
|
12868
12911
|
billingInterval: EnterpriseBillingIntervalSchema,
|
|
12869
12912
|
creditsPerPeriod: external_exports.number().int().positive(),
|
|
12870
12913
|
contractEndAt: external_exports.string().datetime().optional(),
|
|
@@ -13578,10 +13621,13 @@ var publicContract = c16.router(
|
|
|
13578
13621
|
complete: uploadContract.complete
|
|
13579
13622
|
},
|
|
13580
13623
|
asset: {
|
|
13581
|
-
// Semantic/filename search of the team's Files (DAM) library,
|
|
13582
|
-
//
|
|
13583
|
-
//
|
|
13624
|
+
// Semantic/filename search of the team's Files (DAM) library,
|
|
13625
|
+
// listing the library's folders (to resolve a folder name → id for a
|
|
13626
|
+
// folder-scoped search), and placing a found asset onto a canvas by
|
|
13627
|
+
// reference (no duplicate). All gated to Pro + Enterprise by the
|
|
13628
|
+
// handlers.
|
|
13584
13629
|
search: filesContract.searchAgentAssets,
|
|
13630
|
+
folders: filesContract.listAgentAssetFolders,
|
|
13585
13631
|
place: canvasContract.placeLibraryAssets
|
|
13586
13632
|
},
|
|
13587
13633
|
model: {
|
|
@@ -13848,7 +13894,7 @@ function isMajorUpgrade(current, latest) {
|
|
|
13848
13894
|
return l[0] > c17[0];
|
|
13849
13895
|
}
|
|
13850
13896
|
function shouldShowUpgradeNotice(ctx = {}) {
|
|
13851
|
-
const current = ctx.current ?? "0.
|
|
13897
|
+
const current = ctx.current ?? "0.7.0";
|
|
13852
13898
|
const latest = ctx.latest ?? serverLatestVersion;
|
|
13853
13899
|
const env = ctx.env ?? process.env;
|
|
13854
13900
|
const isTty = ctx.isTty ?? Boolean(process.stderr.isTTY);
|
|
@@ -13869,7 +13915,7 @@ Upgrade: npm install -g @melius-ai/cli@latest (or: brew update && brew upgrade
|
|
|
13869
13915
|
function printUpgradeNoticeIfNeeded(ctx = {}) {
|
|
13870
13916
|
try {
|
|
13871
13917
|
if (!shouldShowUpgradeNotice(ctx)) return;
|
|
13872
|
-
const current = ctx.current ?? "0.
|
|
13918
|
+
const current = ctx.current ?? "0.7.0";
|
|
13873
13919
|
const latest = ctx.latest ?? serverLatestVersion;
|
|
13874
13920
|
process.stderr.write(formatUpgradeNotice(current, latest));
|
|
13875
13921
|
} catch {
|
|
@@ -18553,10 +18599,10 @@ function registerAssetCommands(program2, getOutputOpts) {
|
|
|
18553
18599
|
"Search and place the team's Files (DAM) library assets. Requires a Pro or Enterprise plan"
|
|
18554
18600
|
);
|
|
18555
18601
|
asset.command("search").description(
|
|
18556
|
-
"Search the team's Files/DAM library (uploads + past generations) by meaning (semantic), with exact filename/title matches ranked first. Returns up to 20 relevant matches per page"
|
|
18602
|
+
"Search the team's Files/DAM library (uploads + past generations) by meaning (semantic), with exact filename/title matches ranked first. Returns up to 20 relevant matches per page. Scope to a folder with --folder-id; omit the query and pass --folder-id to bring in the WHOLE folder"
|
|
18557
18603
|
).argument(
|
|
18558
|
-
"
|
|
18559
|
-
'Search terms \u2014 a filename or a description of the content, e.g. "Product_Shot_05" or "black jacket shot"'
|
|
18604
|
+
"[query]",
|
|
18605
|
+
'Search terms \u2014 a filename or a description of the content, e.g. "Product_Shot_05" or "black jacket shot". Optional: OMIT it and pass --folder-id to list EVERY asset in that folder'
|
|
18560
18606
|
).option("--limit <n>", "Max results per page (1-20, default 20)", "20").option(
|
|
18561
18607
|
"--offset <n>",
|
|
18562
18608
|
"Skip the first N matches to page deeper (default 0). Page with --limit until the running count reaches the response's total",
|
|
@@ -18567,23 +18613,41 @@ function registerAssetCommands(program2, getOutputOpts) {
|
|
|
18567
18613
|
).option(
|
|
18568
18614
|
"--canvas-id <canvasId>",
|
|
18569
18615
|
"Scope to one canvas's assets (a filename match within that canvas). Omit to search the whole team library by meaning, exact matches first (the default)"
|
|
18616
|
+
).option(
|
|
18617
|
+
"--folder-id <folderId>",
|
|
18618
|
+
"Scope to one Files folder AND its subfolders. WITH a query, filters within the folder; WITHOUT a query, returns every asset in the folder. Get folder ids from mel asset folders"
|
|
18570
18619
|
).addHelpText(
|
|
18571
18620
|
"after",
|
|
18572
18621
|
`
|
|
18573
18622
|
Returns: { query, total, results: [{ assetId, filename, displayName, fileType, contentType, previewUrl, assetUrl, durationInMs }] }.
|
|
18574
18623
|
total is the full match count; page through it with --limit + --offset.
|
|
18575
18624
|
Use the returned assetId values with mel asset place to bring them onto a canvas.
|
|
18625
|
+
Resolve a folder name to an id with mel asset folders first.
|
|
18576
18626
|
|
|
18577
18627
|
Examples:
|
|
18578
18628
|
$ mel asset search "black jacket shot"
|
|
18579
18629
|
$ mel asset search "logo" --file-type image --limit 10
|
|
18580
|
-
$ mel asset search "logo" --limit 20 --offset 20
|
|
18630
|
+
$ mel asset search "logo" --limit 20 --offset 20
|
|
18631
|
+
$ mel asset search "shark" --folder-id <folderId> # find within a folder
|
|
18632
|
+
$ mel asset search --folder-id <folderId> # bring in the WHOLE folder`
|
|
18581
18633
|
).action(
|
|
18582
18634
|
async (query, opts) => {
|
|
18635
|
+
if (query === void 0 && opts.folderId === void 0) {
|
|
18636
|
+
writeError(
|
|
18637
|
+
formatError(
|
|
18638
|
+
"USAGE_ERROR",
|
|
18639
|
+
"Provide a search query, or --folder-id to bring in a whole folder",
|
|
18640
|
+
{
|
|
18641
|
+
suggestion: "Run mel asset folders to list folder ids, then: mel asset search --folder-id <folderId>"
|
|
18642
|
+
}
|
|
18643
|
+
),
|
|
18644
|
+
EXIT_USAGE_ERROR
|
|
18645
|
+
);
|
|
18646
|
+
}
|
|
18583
18647
|
const client = getClient();
|
|
18584
18648
|
const result = await client.asset.search({
|
|
18585
18649
|
query: {
|
|
18586
|
-
query,
|
|
18650
|
+
...query !== void 0 && { query },
|
|
18587
18651
|
limit: Number(opts.limit),
|
|
18588
18652
|
offset: Number(opts.offset),
|
|
18589
18653
|
...opts.fileType !== void 0 && {
|
|
@@ -18591,6 +18655,9 @@ Examples:
|
|
|
18591
18655
|
},
|
|
18592
18656
|
...opts.canvasId !== void 0 && {
|
|
18593
18657
|
canvasId: opts.canvasId
|
|
18658
|
+
},
|
|
18659
|
+
...opts.folderId !== void 0 && {
|
|
18660
|
+
folderId: opts.folderId
|
|
18594
18661
|
}
|
|
18595
18662
|
}
|
|
18596
18663
|
});
|
|
@@ -18604,6 +18671,31 @@ Examples:
|
|
|
18604
18671
|
writeJson(result.body, getOutputOpts());
|
|
18605
18672
|
}
|
|
18606
18673
|
);
|
|
18674
|
+
asset.command("folders").description(
|
|
18675
|
+
"List the team's Files/DAM folders (id, name, full path, file count). Use a folder's id with mel asset search --folder-id to scope a search or bring in the whole folder"
|
|
18676
|
+
).addHelpText(
|
|
18677
|
+
"after",
|
|
18678
|
+
`
|
|
18679
|
+
Returns: an array of { id, name, path, fileCount }.
|
|
18680
|
+
path is the folder's location from the library root (e.g. "Brand / Logos") \u2014 use it to disambiguate same-named folders.
|
|
18681
|
+
Pass a folder id to mel asset search --folder-id <folderId>.
|
|
18682
|
+
|
|
18683
|
+
Examples:
|
|
18684
|
+
$ mel asset folders
|
|
18685
|
+
$ mel asset folders --text`
|
|
18686
|
+
).action(async () => {
|
|
18687
|
+
const client = getClient();
|
|
18688
|
+
const result = await client.asset.folders();
|
|
18689
|
+
if (result.status !== 200) {
|
|
18690
|
+
handleApiError(
|
|
18691
|
+
result.status,
|
|
18692
|
+
result.body,
|
|
18693
|
+
result.status === 403 ? ASSET_PLAN_REQUIRED_SUGGESTION : void 0
|
|
18694
|
+
);
|
|
18695
|
+
}
|
|
18696
|
+
const body = result.body;
|
|
18697
|
+
writeJson(body.folders, getOutputOpts());
|
|
18698
|
+
});
|
|
18607
18699
|
asset.command("place").description(
|
|
18608
18700
|
"Place existing library assets onto a canvas by id, referencing the ORIGINAL asset (no duplicate, no re-upload). Creates file nodes server-side (writes to CRDT) and returns their node ids"
|
|
18609
18701
|
).argument(
|
|
@@ -18773,7 +18865,7 @@ function withDefaultHelp(args) {
|
|
|
18773
18865
|
}
|
|
18774
18866
|
function createProgram() {
|
|
18775
18867
|
const program2 = new Command();
|
|
18776
|
-
program2.name("mel").description("Mel \u2014 Melius agent CLI").version("0.
|
|
18868
|
+
program2.name("mel").description("Mel \u2014 Melius agent CLI").version("0.7.0").showSuggestionAfterError(true).option("--json", "Force JSON output (default)").option("--text", "Human-readable output").option(
|
|
18777
18869
|
"--fields <fields>",
|
|
18778
18870
|
"Select specific output fields (comma-separated)"
|
|
18779
18871
|
).option("--quiet", "Suppress output, exit code only").option("--verbose", "Log request/response metadata to stderr").addHelpText(
|
package/dist/src/index.js
CHANGED