ente-cli 0.4.104 → 0.4.105
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 +1 -1
- package/dist/SKILL.md +3 -1
- package/dist/cli.mjs +120 -3
- package/dist/cli.mjs.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -192,7 +192,7 @@ Every command supports `--json`. Run `ente --help` or `ente <group> --help`.
|
|
|
192
192
|
| `recording` | `list`, `show`, `inspect`, `rerun`, `orphans`, `backups` (platform key) |
|
|
193
193
|
| `admin` | `tables`, `get`, `page` — read-only inspector over any table (platform key) |
|
|
194
194
|
| `canvas` | `boards`, `html list`, `html get`, `html create`, `html update`, `html delete` |
|
|
195
|
-
| `files` | `list`, `upload` (local file at most 10 MiB, or an activity attachment), `link`, `create-folder` — the entity's Nextcloud folder via your own connection; personal agent key only (MCP: `entity_files_list`, `entity_file_upload`, `entity_folder_link`, `entity_folder_create`) |
|
|
195
|
+
| `files` | `list`, `search` (by name, all subfolders), `read` (text of a PDF, DOCX or plain-text file up to 10 MiB, in windows of 50,000 characters), `upload` (local file at most 10 MiB, or an activity attachment), `link`, `create-folder` — the entity's Nextcloud folder via your own connection; personal agent key only (MCP: `entity_files_list`, `entity_files_search`, `entity_file_read`, `entity_file_upload`, `entity_folder_link`, `entity_folder_create`) |
|
|
196
196
|
| `notification` | `send` (emails only your own Ente account address; optional HTML, file attachments, and CID inline images) |
|
|
197
197
|
| `agent` | `permissions`, `list`, `threads`, `show`, `new`, `send`, `config show`, `config set-prompt`, `schedules configure` |
|
|
198
198
|
| `agent mail` | `address`, `threads`, `show`, `send`, `reply`, `mark` |
|
package/dist/SKILL.md
CHANGED
|
@@ -254,8 +254,10 @@ ente canvas html delete <boardId> <elementId> [--json]
|
|
|
254
254
|
|
|
255
255
|
# Entity files: the entity's linked Nextcloud folder, through YOUR own Nextcloud
|
|
256
256
|
# connection. Works only with your personal agent's key; shared agents are refused.
|
|
257
|
-
# MCP/REST: entity_files_list, entity_file_upload, entity_folder_link, entity_folder_create.
|
|
257
|
+
# MCP/REST: entity_files_list, entity_files_search, entity_file_read, entity_file_upload, entity_folder_link, entity_folder_create.
|
|
258
258
|
ente files list <entityId> [--path "03 Unterlagen"] [--json] # --json: linkedFolderPath = the linked folder's path from your Nextcloud root; join it with an item path for the exact file
|
|
259
|
+
ente files search <entityId> "Mietvertrag" [--json] # name search in all subfolders of the linked folder
|
|
260
|
+
ente files read <entityId> "03 Unterlagen/Mietvertrag.pdf" [--offset N] [--max-characters N] [--json] # text of a PDF (text layer), DOCX or plain-text file up to 100 MiB, 50,000 characters per call; a scan without text layer returns notice no_text_layer
|
|
259
261
|
ente files upload <entityId> <local-file> [--folder "03 Unterlagen"] [--name "Vertrag.pdf"] [--mime-type application/pdf] [--json] # at most 10 MiB
|
|
260
262
|
ente files upload <entityId> --activity <activityId> --storage-id <storageId> --name "Vertrag.pdf" [--folder …] [--json] # copy an activity attachment
|
|
261
263
|
ente files link <entityId> "Mandate/2026-017 Zebrafink" [--space <spaceId>] [--json]
|
package/dist/cli.mjs
CHANGED
|
@@ -8055,7 +8055,7 @@ async function runCli(cli2, argv, context) {
|
|
|
8055
8055
|
}
|
|
8056
8056
|
|
|
8057
8057
|
// ente/version.ts
|
|
8058
|
-
var VERSION = "0.4.
|
|
8058
|
+
var VERSION = "0.4.105";
|
|
8059
8059
|
|
|
8060
8060
|
// ente/branding.ts
|
|
8061
8061
|
var NPM_REGISTRY = "https://registry.npmjs.org";
|
|
@@ -47336,11 +47336,51 @@ var entityFileListResultValidator = v.union(
|
|
|
47336
47336
|
}),
|
|
47337
47337
|
v.object({ status: v.union(...ENTITY_FILE_LIST_PROBLEM_STATUSES.map((status2) => v.literal(status2))) })
|
|
47338
47338
|
);
|
|
47339
|
+
var problemStatusValidator = v.object({ status: v.union(...ENTITY_FILE_LIST_PROBLEM_STATUSES.map((status2) => v.literal(status2))) });
|
|
47340
|
+
var entityFileSearchResultValidator = v.union(
|
|
47341
|
+
v.object({
|
|
47342
|
+
status: v.literal("ok"),
|
|
47343
|
+
/** The linked folder itself, relative to the caller's own Nextcloud root; read live, never stored. */
|
|
47344
|
+
linkedFolderPath: v.string(),
|
|
47345
|
+
items: v.array(entityFileItemValidator),
|
|
47346
|
+
/** More hits exist than returned; narrow the query. */
|
|
47347
|
+
truncated: v.boolean()
|
|
47348
|
+
}),
|
|
47349
|
+
problemStatusValidator
|
|
47350
|
+
);
|
|
47351
|
+
var entityFileReadResultValidator = v.union(
|
|
47352
|
+
v.object({
|
|
47353
|
+
status: v.literal("ok"),
|
|
47354
|
+
/** The file, relative to the linked folder. */
|
|
47355
|
+
path: v.string(),
|
|
47356
|
+
name: v.string(),
|
|
47357
|
+
mimeType: v.union(v.string(), v.null()),
|
|
47358
|
+
size: v.union(v.number(), v.null()),
|
|
47359
|
+
modifiedAt: v.union(v.number(), v.null()),
|
|
47360
|
+
format: v.union(v.literal("text"), v.literal("pdf"), v.literal("docx")),
|
|
47361
|
+
/** The returned window of the extracted text. */
|
|
47362
|
+
text: v.string(),
|
|
47363
|
+
/** Character offset of `text` in the whole extracted text. */
|
|
47364
|
+
offset: v.number(),
|
|
47365
|
+
totalCharacters: v.number(),
|
|
47366
|
+
/** Text continues after this window; call again with offset + text.length. */
|
|
47367
|
+
truncated: v.boolean(),
|
|
47368
|
+
/**
|
|
47369
|
+
* Set when a PDF has (almost) no text layer, typically a scan: the text is
|
|
47370
|
+
* not the document's content. OCR in Nextcloud (e.g. workflow_ocr) may add
|
|
47371
|
+
* a layer as a new file version shortly after upload.
|
|
47372
|
+
*/
|
|
47373
|
+
notice: v.optional(v.object({ code: v.literal("no_text_layer"), message: v.string() }))
|
|
47374
|
+
}),
|
|
47375
|
+
problemStatusValidator
|
|
47376
|
+
);
|
|
47339
47377
|
var entityFileUploadResultValidator = v.object({ fileId: v.string(), name: v.string(), path: v.string() });
|
|
47340
47378
|
var entityFileResults = {
|
|
47341
47379
|
createEntityFolder: entityFolderLinkResultValidator,
|
|
47342
47380
|
linkEntityFolder: entityFolderLinkResultValidator,
|
|
47343
47381
|
listEntityFiles: entityFileListResultValidator,
|
|
47382
|
+
searchEntityFiles: entityFileSearchResultValidator,
|
|
47383
|
+
readEntityFile: entityFileReadResultValidator,
|
|
47344
47384
|
uploadEntityFile: entityFileUploadResultValidator
|
|
47345
47385
|
};
|
|
47346
47386
|
function parseEntityFileResult(operation, raw) {
|
|
@@ -47360,6 +47400,19 @@ var ENTITY_FILE_LIMITS = {
|
|
|
47360
47400
|
uploadBytes: 20 * 1024 * 1024,
|
|
47361
47401
|
/** A file the panel sends in parts (Nextcloud chunked upload v2); larger ones go into Nextcloud directly. */
|
|
47362
47402
|
chunkedUploadBytes: 500 * 1024 * 1024,
|
|
47403
|
+
/**
|
|
47404
|
+
* Largest file readEntityFile extracts text from, set by the Node action's
|
|
47405
|
+
* memory (512 MiB on Convex cloud). Measured 02.11.2026 in a local Convex
|
|
47406
|
+
* backend (Node action, PDF.js 6.4, synthetic scan-like PDF with a 250 KB
|
|
47407
|
+
* image and a text layer per page): 100 MB / 400 pages raised RSS from 306 to
|
|
47408
|
+
* 499 MiB (+193 MiB, 5.6 s); 200 MB / 800 pages added 114 MiB more on a warm
|
|
47409
|
+
* process (7.1 s). About 1.9 bytes per file byte on a ~306 MiB base gives
|
|
47410
|
+
* (512 - 306) / 1.9 = ~106 MiB, hence 100 MiB. Before, bytes went to Node as
|
|
47411
|
+
* an argument, which Convex caps at 5 MiB for Node actions.
|
|
47412
|
+
*/
|
|
47413
|
+
readBytes: 100 * 1024 * 1024,
|
|
47414
|
+
/** Characters readEntityFile returns per call; longer texts are read in windows. */
|
|
47415
|
+
readCharacters: 5e4,
|
|
47363
47416
|
nameCharacters: 250,
|
|
47364
47417
|
pathCharacters: 4096,
|
|
47365
47418
|
mimeTypeCharacters: 255
|
|
@@ -47393,6 +47446,16 @@ var entityFileInputs = {
|
|
|
47393
47446
|
entityId: id17,
|
|
47394
47447
|
path: path6("Folder inside the linked folder; omit or empty string for the linked folder itself.").optional()
|
|
47395
47448
|
}),
|
|
47449
|
+
searchEntityFiles: external_exports.strictObject({
|
|
47450
|
+
entityId: id17,
|
|
47451
|
+
query: external_exports.string().trim().min(2).max(200).describe("Part of a file or folder name, 2 to 200 characters; matched anywhere below the linked folder.")
|
|
47452
|
+
}),
|
|
47453
|
+
readEntityFile: external_exports.strictObject({
|
|
47454
|
+
entityId: id17,
|
|
47455
|
+
path: external_exports.string().min(1).max(ENTITY_FILE_LIMITS.pathCharacters).describe("File inside the linked folder, as entity_files_list or entity_files_search return it, for example 03 Unterlagen/Mietvertrag.pdf."),
|
|
47456
|
+
offset: external_exports.number().int().min(0).optional().describe("Character offset to continue a truncated text; defaults to 0."),
|
|
47457
|
+
maxCharacters: external_exports.number().int().min(1).max(ENTITY_FILE_LIMITS.readCharacters).optional().describe(`Characters to return, at most ${ENTITY_FILE_LIMITS.readCharacters}; defaults to that maximum.`)
|
|
47458
|
+
}),
|
|
47396
47459
|
uploadEntityFile: external_exports.strictObject({
|
|
47397
47460
|
entityId: id17,
|
|
47398
47461
|
folderPath: path6("Target folder inside the linked folder; defaults to the linked folder itself.").optional(),
|
|
@@ -47409,6 +47472,8 @@ var entityFileAliases = {
|
|
|
47409
47472
|
entity_folder_create: "createEntityFolder",
|
|
47410
47473
|
entity_folder_link: "linkEntityFolder",
|
|
47411
47474
|
entity_files_list: "listEntityFiles",
|
|
47475
|
+
entity_files_search: "searchEntityFiles",
|
|
47476
|
+
entity_file_read: "readEntityFile",
|
|
47412
47477
|
entity_file_upload: "uploadEntityFile"
|
|
47413
47478
|
};
|
|
47414
47479
|
function isEntityFileOperationName(value) {
|
|
@@ -47419,8 +47484,14 @@ var descriptions5 = {
|
|
|
47419
47484
|
createEntityFolder: `Create a new folder in your Nextcloud below parentPath and link it as the entity's file folder. ${personalOnly}`,
|
|
47420
47485
|
linkEntityFolder: `Link an existing folder of your Nextcloud, given by its path, as the entity's file folder. A folder can belong to one entity only. ${personalOnly}`,
|
|
47421
47486
|
listEntityFiles: `List the files and folders in the entity's linked Nextcloud folder. status explains a missing link or connection instead of an empty list. Item paths are relative to the linked folder; linkedFolderPath is the linked folder's own path from your Nextcloud root, so join it with an item path to address that exact file in Nextcloud instead of searching by name. ${personalOnly}`,
|
|
47487
|
+
searchEntityFiles: `Find files and folders by name anywhere below the entity's linked Nextcloud folder, also in subfolders. status explains a missing link or connection; truncated means more hits exist, so narrow the query. Item paths are relative to the linked folder and go unchanged into entity_file_read. ${personalOnly}`,
|
|
47488
|
+
readEntityFile: `Read the text of one file in the entity's linked Nextcloud folder: PDF (text layer only), DOCX and plain-text formats such as TXT, MD, CSV, JSON or XML, up to ${ENTITY_FILE_LIMITS.readBytes / (1024 * 1024)} MiB. Other formats fail with unsupported_format. Long texts come in windows: when truncated is true, call again with offset set to offset plus the returned text's length. A PDF without a usable text layer (a scan) returns notice.code no_text_layer: its text is not the content; OCR in Nextcloud may add a layer shortly after upload, so read it again later instead of concluding the file is empty. ${personalOnly}`,
|
|
47422
47489
|
uploadEntityFile: `Upload a file into the entity's linked Nextcloud folder; a taken name gets a numbered suffix. Send exactly one of base64Content (at most 10 MiB decoded) or activityAttachment (an existing Ente activity attachment). ${personalOnly}`
|
|
47423
47490
|
};
|
|
47491
|
+
var READ_OPERATIONS = /* @__PURE__ */ new Set(["listEntityFiles", "searchEntityFiles", "readEntityFile"]);
|
|
47492
|
+
function isEntityFileReadOperation(operationName) {
|
|
47493
|
+
return READ_OPERATIONS.has(operationName);
|
|
47494
|
+
}
|
|
47424
47495
|
function definition3(operationName) {
|
|
47425
47496
|
const schema = external_exports.toJSONSchema(entityFileInputs[operationName], { io: "input" });
|
|
47426
47497
|
return {
|
|
@@ -47432,7 +47503,7 @@ function definition3(operationName) {
|
|
|
47432
47503
|
errorSchema: operationErrorSchema,
|
|
47433
47504
|
resultSchema: operationResultSchema(entityFileResults[operationName]),
|
|
47434
47505
|
outputSchema: { type: "object", properties: { data: operationResultSchema(entityFileResults[operationName]) }, required: ["data"], additionalProperties: false },
|
|
47435
|
-
capability: operationName
|
|
47506
|
+
capability: isEntityFileReadOperation(operationName) ? "read" : "write",
|
|
47436
47507
|
executionProfile: "full",
|
|
47437
47508
|
resultProjection: "full",
|
|
47438
47509
|
environment: "content",
|
|
@@ -47459,6 +47530,12 @@ var linkFolderRef = makeFunctionReference2(
|
|
|
47459
47530
|
var listRef = makeFunctionReference2(
|
|
47460
47531
|
"entityFileOperations:list"
|
|
47461
47532
|
);
|
|
47533
|
+
var searchRef = makeFunctionReference2(
|
|
47534
|
+
"entityFileOperations:search"
|
|
47535
|
+
);
|
|
47536
|
+
var readRef = makeFunctionReference2(
|
|
47537
|
+
"entityFileOperations:read"
|
|
47538
|
+
);
|
|
47462
47539
|
var uploadRef = makeFunctionReference2(
|
|
47463
47540
|
"entityFileOperations:upload"
|
|
47464
47541
|
);
|
|
@@ -47474,6 +47551,14 @@ async function listEntityFiles(caller, input2) {
|
|
|
47474
47551
|
const args = parseOperationInput("listEntityFiles", entityFileInputs.listEntityFiles, input2);
|
|
47475
47552
|
return parseEntityFileResult("listEntityFiles", await caller.action(listRef, args));
|
|
47476
47553
|
}
|
|
47554
|
+
async function searchEntityFiles(caller, input2) {
|
|
47555
|
+
const args = parseOperationInput("searchEntityFiles", entityFileInputs.searchEntityFiles, input2);
|
|
47556
|
+
return parseEntityFileResult("searchEntityFiles", await caller.action(searchRef, args));
|
|
47557
|
+
}
|
|
47558
|
+
async function readEntityFile(caller, input2) {
|
|
47559
|
+
const args = parseOperationInput("readEntityFile", entityFileInputs.readEntityFile, input2);
|
|
47560
|
+
return parseEntityFileResult("readEntityFile", await caller.action(readRef, args));
|
|
47561
|
+
}
|
|
47477
47562
|
async function uploadEntityFile(caller, input2) {
|
|
47478
47563
|
const args = parseOperationInput("uploadEntityFile", entityFileInputs.uploadEntityFile, input2);
|
|
47479
47564
|
return parseEntityFileResult("uploadEntityFile", await caller.action(uploadRef, args));
|
|
@@ -47519,6 +47604,38 @@ var FilesListCmd = class extends ProfileCommand {
|
|
|
47519
47604
|
this.emitText({ data }, () => data.status !== "ok" ? `Unavailable: ${data.status}` : [`Linked folder: ${data.linkedFolderPath}`, ...data.items.length ? data.items.map((item) => `${item.isFolder ? "dir " : "file"} ${item.path}${item.size === null ? "" : ` ${item.size} B`}`) : ["Empty folder."]].join("\n"));
|
|
47520
47605
|
}
|
|
47521
47606
|
};
|
|
47607
|
+
var FilesSearchCmd = class extends ProfileCommand {
|
|
47608
|
+
static paths = [["files", "search"]];
|
|
47609
|
+
static usage = Command.Usage({ category: "Files", description: "Find files and folders by name anywhere below the entity's linked Nextcloud folder" });
|
|
47610
|
+
entityId = options_exports.String({ required: true });
|
|
47611
|
+
query = options_exports.String({ required: true });
|
|
47612
|
+
async run() {
|
|
47613
|
+
const data = await searchEntityFiles(await resolveCaller(), { entityId: this.entityId, query: this.query });
|
|
47614
|
+
this.emitText({ data }, () => data.status !== "ok" ? `Unavailable: ${data.status}` : [
|
|
47615
|
+
...data.items.length ? data.items.map((item) => `${item.isFolder ? "dir " : "file"} ${item.path}`) : ["No matches."],
|
|
47616
|
+
...data.truncated ? ["More matches exist; narrow the query."] : []
|
|
47617
|
+
].join("\n"));
|
|
47618
|
+
}
|
|
47619
|
+
};
|
|
47620
|
+
var FilesReadCmd = class extends ProfileCommand {
|
|
47621
|
+
static paths = [["files", "read"]];
|
|
47622
|
+
static usage = Command.Usage({ category: "Files", description: "Print the text of a PDF, DOCX or plain-text file in the entity's linked Nextcloud folder" });
|
|
47623
|
+
entityId = options_exports.String({ required: true });
|
|
47624
|
+
filePath = options_exports.String({ required: true });
|
|
47625
|
+
offset = options_exports.String("--offset", { description: "Character offset to continue a truncated text" });
|
|
47626
|
+
maxCharacters = options_exports.String("--max-characters", { description: "Characters to return per call" });
|
|
47627
|
+
async run() {
|
|
47628
|
+
const data = await readEntityFile(await resolveCaller(), {
|
|
47629
|
+
entityId: this.entityId,
|
|
47630
|
+
path: this.filePath,
|
|
47631
|
+
...this.offset === void 0 ? {} : { offset: Number(this.offset) },
|
|
47632
|
+
...this.maxCharacters === void 0 ? {} : { maxCharacters: Number(this.maxCharacters) }
|
|
47633
|
+
});
|
|
47634
|
+
this.emitText({ data }, () => data.status !== "ok" ? `Unavailable: ${data.status}` : [...data.notice ? [`[${data.notice.code}] ${data.notice.message}
|
|
47635
|
+
`] : [], data.text, ...data.truncated ? [`
|
|
47636
|
+
[${data.offset + data.text.length} of ${data.totalCharacters} characters; continue with --offset ${data.offset + data.text.length}]`] : []].join("\n"));
|
|
47637
|
+
}
|
|
47638
|
+
};
|
|
47522
47639
|
var FilesUploadCmd = class extends ProfileCommand {
|
|
47523
47640
|
static paths = [["files", "upload"]];
|
|
47524
47641
|
static usage = Command.Usage({
|
|
@@ -47580,7 +47697,7 @@ var FilesCreateFolderCmd = class extends ProfileCommand {
|
|
|
47580
47697
|
this.emitText({ data }, () => `Created and linked ${data.path}`);
|
|
47581
47698
|
}
|
|
47582
47699
|
};
|
|
47583
|
-
var FILES_COMMANDS = [FilesListCmd, FilesUploadCmd, FilesLinkCmd, FilesCreateFolderCmd];
|
|
47700
|
+
var FILES_COMMANDS = [FilesListCmd, FilesSearchCmd, FilesReadCmd, FilesUploadCmd, FilesLinkCmd, FilesCreateFolderCmd];
|
|
47584
47701
|
|
|
47585
47702
|
// ente/commands/notification.ts
|
|
47586
47703
|
import { readFileSync as readFileSync15 } from "node:fs";
|