@corvio/cli 0.1.0-beta.35 → 0.1.0-beta.36
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 +4 -4
- package/dist/cli.js +106 -8
- package/dist/core.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,9 +12,9 @@ corvio collaboration status --json --no-input
|
|
|
12
12
|
corvio ask --prompt 'Summarize recurring launch risks' --json
|
|
13
13
|
corvio files upload --file ./research.pdf --json
|
|
14
14
|
corvio files get <asset_id> --content --json
|
|
15
|
-
corvio files organize <asset_id> --instruction 'Create a reusable decision brief' --yes --json
|
|
16
|
-
corvio files operation <operation_id> --json
|
|
17
|
-
corvio files resume <operation_id> --yes --json
|
|
15
|
+
corvio files organize <asset_id> --instruction 'Create a reusable decision brief' --yes --wait-until-terminal --timeout-seconds 1200 --json
|
|
16
|
+
corvio files operation <operation_id> --wait-until-terminal --timeout-seconds 1200 --json
|
|
17
|
+
corvio files resume <operation_id> --yes --wait-until-terminal --timeout-seconds 1200 --json
|
|
18
18
|
corvio docs read <workspace_id/document_id> --mode auto --json
|
|
19
19
|
corvio docs patch <workspace_id/document_id> --input ./patch.json --operation-id <id> --yes --json
|
|
20
20
|
corvio docs table-read <workspace_id/document_id> --limit 25 --json
|
|
@@ -47,7 +47,7 @@ Treat files as a value ladder, not one upload event. Upload/finalize preserves t
|
|
|
47
47
|
|
|
48
48
|
Use `corvio files get <asset_id> --content` when the task needs only bounded facts from one retained source. The response preserves the immutable original as authority, reports its source hash and whether the projection is complete or truncated, and does not create a Question or materialize another document. Never infer unseen workbook rows/sheets or document sections.
|
|
49
49
|
|
|
50
|
-
File organization is asynchronous. A queued organization receipt is progress, not completion
|
|
50
|
+
File organization is asynchronous. A queued organization receipt is progress, not completion. When this authenticated CLI is already the natural transport, `--wait-until-terminal` keeps deterministic status reads inside one foreground process; `--timeout-seconds` is a bounded local deadline, and expiry returns the latest non-terminal receipt with `transport_wait.status=deadline_reached`. Without that flag, `corvio files operation <operation_id>` remains one immediate read. Blocked operations expose their typed error and can be continued with `corvio files resume <operation_id> --yes`; queued/running/blocked operations can be stopped with `corvio files cancel <operation_id> --yes`. Report completion only after the terminal receipt exposes the output document, source reconciliation, Skill evaluation, and durable links. `skills_extraction_mode=always` requires the evaluation; `evaluated_no_qualifying_skill` is a valid terminal result and is preferable to a fabricated Skill.
|
|
51
51
|
|
|
52
52
|
## Project Agent collaboration
|
|
53
53
|
|
package/dist/cli.js
CHANGED
|
@@ -39,13 +39,16 @@ import {
|
|
|
39
39
|
agentCredentialPath,
|
|
40
40
|
} from "./core.js";
|
|
41
41
|
|
|
42
|
-
const VERSION = "0.1.0-beta.
|
|
42
|
+
const VERSION = "0.1.0-beta.36";
|
|
43
43
|
const DEFAULT_API_BASE = "https://api.corvio.ai/v1";
|
|
44
44
|
const DEFAULT_APP_BASE = "https://corvio.ai";
|
|
45
45
|
const USER_AGENT = `corvio-cli/${VERSION}`;
|
|
46
46
|
const MAX_UPLOAD_BYTES = 100 * 1024 * 1024;
|
|
47
47
|
const MAX_SYNC_FILES = 2_000;
|
|
48
48
|
const MAX_MARKDOWN_CHARACTERS = 120_000;
|
|
49
|
+
const DEFAULT_FILE_OPERATION_WAIT_TIMEOUT_SECONDS = 1_200;
|
|
50
|
+
const MAX_FILE_OPERATION_WAIT_TIMEOUT_SECONDS = 7_200;
|
|
51
|
+
const FILE_OPERATION_PENDING_STATUSES = new Set(["accepted", "pending", "prepared", "queued", "running"]);
|
|
49
52
|
const CORVIO_SKILL_ARCHIVE = "https://corvio.ai/developers/skills/corvio-operate-workspace/corvio-operate-workspace.zip";
|
|
50
53
|
const AGENT_SKILLS_INSTALLER_VERSION = "1.5.23";
|
|
51
54
|
const GLOBAL_OPTIONS = Object.freeze([
|
|
@@ -126,13 +129,15 @@ const COMMAND_OPTIONS = Object.freeze({
|
|
|
126
129
|
"files:upload": [
|
|
127
130
|
"file", "mime-type", "organize", "instruction", "target-root-node-id", "additional-asset-ids",
|
|
128
131
|
"processing-profile", "max-processing-profile", "scan-mode", "skills-extraction-mode", "caller-model",
|
|
132
|
+
"wait-until-terminal", "timeout-seconds",
|
|
129
133
|
],
|
|
130
134
|
"files:organize": [
|
|
131
135
|
"id", "additional-asset-ids", "instruction", "target-root-node-id",
|
|
132
136
|
"processing-profile", "max-processing-profile", "scan-mode", "skills-extraction-mode", "caller-model",
|
|
137
|
+
"wait-until-terminal", "timeout-seconds",
|
|
133
138
|
],
|
|
134
|
-
"files:operation": ["id"],
|
|
135
|
-
"files:resume": ["id"],
|
|
139
|
+
"files:operation": ["id", "wait-until-terminal", "timeout-seconds"],
|
|
140
|
+
"files:resume": ["id", "wait-until-terminal", "timeout-seconds"],
|
|
136
141
|
"files:cancel": ["id"],
|
|
137
142
|
"files:open": ["id"],
|
|
138
143
|
"sync:init": ["root-node-id", "dir", "name", "force"],
|
|
@@ -188,7 +193,7 @@ const COMMAND_HELP = Object.freeze({
|
|
|
188
193
|
search: `Usage: corvio search <query> [--limit <n>] [--page-id <id>] [--node-id <id>]`,
|
|
189
194
|
docs: `Usage:\n corvio docs list [--limit <n>] [--cursor <cursor>] [--lifecycle active|archived]\n corvio docs get <id> [--output <path>]\n corvio docs read <id> [--mode auto|overview|line-range|section|search|full] [--start-line <n> --end-line <n>|--section-ref <S#>|--query <text>] [--max-chars <n>]\n corvio docs patch <id> --input <json> --yes [--operation-id <id>] [--change-summary <text>]\n corvio docs table-read <id> [--table-id <id>] [--after-row-id <id>] [--limit <1-100>]\n corvio docs table-mutate <id> --input <json> --yes [--operation-id <id>] [--change-summary <text>]\n corvio docs create --title <title> [--file <path>|--markdown <text>] [--parent-node-id <id>] [--idempotency-key <key>]\n corvio docs update <id> [--title <title>] [--file <path>|--markdown <text>] [--expected-revision <n>] [--change-summary <text>]\n corvio docs move <id> --parent-node-id <id>\n corvio docs archive <id> --yes\n corvio docs restore <id> --yes\n corvio docs share <id> --yes [--display-name <name>]\n corvio docs open <id>\n\nUse \`docs read --mode auto\` first for a small full body or a large-document overview, then read an exact section or line range. Use \`docs patch\` when the host already knows 1-20 exact L# replacements; it preserves untouched lines and returns a compact verified delta. A selected Markdown file can become an editable Page without resending the body through the model. Use \`docs update\` only when whole-body replacement is the smallest faithful change. Delegate document-wide judgment, cross-source synthesis, structure/formatting interpretation, and typed Spreadsheet, Presentation, Code, or HTML work to \`corvio ask --allow-actions\`. A Project is a structure container; body writes fail with project_structure_container_body_write_disabled, while a title-only Project rename remains valid. Projects stay at the Workspace root and cannot be nested; use \`files organize\` or \`ask --allow-actions\` for Work Model maintenance. Use table-read plus table-mutate for bounded stable-ID cell updates or row appends. Agent-authenticated document changes require --change-summary and create a visible document-level comment after the guarded update. When a document/comment is the task owner, use \`corvio agent closeout\` to return verified work to that same collaboration surface and read it back.`,
|
|
190
195
|
projects: `Usage:\n corvio projects list [--limit <n>]\n corvio projects create --title <title> [--idempotency-key <key>]\n\nProjects are durable root-level grouping owners in the Corvio Docs tree and cannot be nested under another Project. Reuse a matching Project instead of creating one ceremonial Project per file; use semantic branch Pages and leaves for deeper Work Models. 'corvio folders' is an alias.`,
|
|
191
|
-
files: `Usage:\n corvio files list [--limit <n>]\n corvio files get <id> [--content]\n corvio files download <id> [--output <path>]\n corvio files upload --file <path> [--mime-type <type>] [--organize --instruction <text> --additional-asset-ids <id,id> --yes]\n corvio files organize <id> --instruction <text> --yes [--additional-asset-ids <id,id>] [--target-root-node-id <project-node-id>] [--processing-profile auto|economy|standard|deep] [--scan-mode auto|always|off] [--skills-extraction-mode auto|always|off]\n corvio files operation <operation-id
|
|
196
|
+
files: `Usage:\n corvio files list [--limit <n>]\n corvio files get <id> [--content]\n corvio files download <id> [--output <path>]\n corvio files upload --file <path> [--mime-type <type>] [--organize --instruction <text> --additional-asset-ids <id,id> --yes] [--wait-until-terminal] [--timeout-seconds <1-7200>]\n corvio files organize <id> --instruction <text> --yes [--additional-asset-ids <id,id>] [--target-root-node-id <project-node-id>] [--processing-profile auto|economy|standard|deep] [--scan-mode auto|always|off] [--skills-extraction-mode auto|always|off] [--wait-until-terminal] [--timeout-seconds <1-7200>]\n corvio files operation <operation-id> [--wait-until-terminal] [--timeout-seconds <1-7200>]\n corvio files resume <operation-id> --yes [--wait-until-terminal] [--timeout-seconds <1-7200>]\n corvio files cancel <operation-id> --yes\n corvio files open <id>\n\nUse --content only when source facts are needed. It returns one bounded AI-safe projection with hash, completeness, and truncation receipts; it does not rewrite or materialize the original. Upload alone preserves the exact original, provenance, hash, policy, and stable Asset ID. Organization is a separate asynchronous value step: one coherent source set can produce reader-facing structure, source reconciliation, Memory candidates, and qualifying Project Skills. Pass --instruction a weak natural goal plus explicit user constraints and only authority facts needed to prevent wrong identity or scope. Keep source-derived facts in the source; do not precompute an outline, edit checklist, taxonomy, titles, artifact count, or sole leaf target from current visibility. A heterogeneous source may update several real Projects while its provenance carrier stays a standalone document; do not direct Corvio to make the source Page an umbrella Project. For a newly finalized Asset that should enter a Work Model or Skill evaluation, use one organize operation as the sole semantic owner; do not open ask before or after it for the same Asset set. --target-root-node-id is optional and accepts only a Project node_id returned by projects list, never a Page/document UUID or leaf node; omit it when the Project is not known. Use --wait-until-terminal when a filesystem-capable Host should keep deterministic polling inside this one foreground CLI invocation; --timeout-seconds is a local wait deadline, and reaching it returns the latest non-terminal receipt rather than claiming completion. Without that flag, 'files operation' remains an immediate read. Inspect terminal output_document plus skills_evaluation; evaluated_no_qualifying_skill is valid. Resume reuses the same durable operation after resolving its blocker; cancel is idempotent.`,
|
|
192
197
|
sync: `Usage:\n corvio sync init --root-node-id <id> [--dir <path>] [--name <name>]\n corvio sync status|plan|pull [--dir <path>]\n corvio sync push --yes [--dir <path>]\n corvio sync resolve --conflict-id <id> --strategy use-remote|keep-local --yes [--dir <path>]`,
|
|
193
198
|
update: `Usage: corvio update check [--json]\n\nCompare this executable with the reviewed API policy and the npm beta dist-tag.`,
|
|
194
199
|
});
|
|
@@ -3456,7 +3461,77 @@ async function uploadWorkspaceFile(api, inputPath, mimeTypeOverride) {
|
|
|
3456
3461
|
return result;
|
|
3457
3462
|
}
|
|
3458
3463
|
|
|
3464
|
+
function fileOperationWaitTimeoutSeconds(options) {
|
|
3465
|
+
if (!options["wait-until-terminal"]) {
|
|
3466
|
+
if (options["timeout-seconds"] !== undefined) {
|
|
3467
|
+
throw new CliError("--timeout-seconds requires --wait-until-terminal.", {
|
|
3468
|
+
code: "file_operation_wait_required",
|
|
3469
|
+
});
|
|
3470
|
+
}
|
|
3471
|
+
return null;
|
|
3472
|
+
}
|
|
3473
|
+
return numberOption(
|
|
3474
|
+
options,
|
|
3475
|
+
"timeout-seconds",
|
|
3476
|
+
DEFAULT_FILE_OPERATION_WAIT_TIMEOUT_SECONDS,
|
|
3477
|
+
{ minimum: 1, maximum: MAX_FILE_OPERATION_WAIT_TIMEOUT_SECONDS },
|
|
3478
|
+
);
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3481
|
+
function fileOperationIsPending(result) {
|
|
3482
|
+
return FILE_OPERATION_PENDING_STATUSES.has(String(result?.status || "").trim().toLowerCase());
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3485
|
+
function fileOperationDeadlineReceipt(result, { timeoutSeconds, startedAtMs, operationReadCount }) {
|
|
3486
|
+
return {
|
|
3487
|
+
...result,
|
|
3488
|
+
transport_wait: {
|
|
3489
|
+
status: "deadline_reached",
|
|
3490
|
+
terminal: false,
|
|
3491
|
+
timeout_seconds: timeoutSeconds,
|
|
3492
|
+
elapsed_seconds: Math.max(0, Math.round((Date.now() - startedAtMs) / 1000)),
|
|
3493
|
+
operation_read_count: operationReadCount,
|
|
3494
|
+
continuation: "Run the same files operation command with --wait-until-terminal; do not start a replacement operation.",
|
|
3495
|
+
},
|
|
3496
|
+
};
|
|
3497
|
+
}
|
|
3498
|
+
|
|
3499
|
+
async function waitForFileOperation(api, operationId, { initialResult = null, timeoutSeconds }) {
|
|
3500
|
+
const startedAtMs = Date.now();
|
|
3501
|
+
const deadlineAtMs = startedAtMs + timeoutSeconds * 1000;
|
|
3502
|
+
let result = initialResult;
|
|
3503
|
+
let operationReadCount = 0;
|
|
3504
|
+
while (true) {
|
|
3505
|
+
if (!result) {
|
|
3506
|
+
result = await api.request(`/file-operations/${resourcePath(operationId)}`);
|
|
3507
|
+
operationReadCount += 1;
|
|
3508
|
+
}
|
|
3509
|
+
if (!fileOperationIsPending(result)) return result;
|
|
3510
|
+
|
|
3511
|
+
const remainingMs = deadlineAtMs - Date.now();
|
|
3512
|
+
if (remainingMs <= 0) {
|
|
3513
|
+
return fileOperationDeadlineReceipt(result, {
|
|
3514
|
+
timeoutSeconds,
|
|
3515
|
+
startedAtMs,
|
|
3516
|
+
operationReadCount,
|
|
3517
|
+
});
|
|
3518
|
+
}
|
|
3519
|
+
const retryAfterSeconds = Number(result.retry_after_seconds);
|
|
3520
|
+
const requestedDelayMs = Number.isFinite(retryAfterSeconds) && retryAfterSeconds >= 0
|
|
3521
|
+
? retryAfterSeconds * 1000
|
|
3522
|
+
: 5_000;
|
|
3523
|
+
await sleep(Math.min(remainingMs, Math.max(50, Math.min(30_000, requestedDelayMs))));
|
|
3524
|
+
result = null;
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
|
|
3459
3528
|
async function files(options, action, id) {
|
|
3529
|
+
const waitTimeoutSeconds = fileOperationWaitTimeoutSeconds(options);
|
|
3530
|
+
if (action === "upload" && waitTimeoutSeconds !== null && !options.organize) {
|
|
3531
|
+
throw new CliError("--wait-until-terminal requires --organize for files upload.", {
|
|
3532
|
+
code: "file_operation_wait_requires_organize",
|
|
3533
|
+
});
|
|
3534
|
+
}
|
|
3460
3535
|
const { api } = await executionClient(options);
|
|
3461
3536
|
const assetId = id || options.id;
|
|
3462
3537
|
let result;
|
|
@@ -3492,27 +3567,50 @@ async function files(options, action, id) {
|
|
|
3492
3567
|
headers: options["caller-model"] ? { "x-corvio-caller-model": String(options["caller-model"]) } : {},
|
|
3493
3568
|
body: fileOrganizationBody(options),
|
|
3494
3569
|
});
|
|
3495
|
-
result = {
|
|
3570
|
+
result = {
|
|
3571
|
+
file: result,
|
|
3572
|
+
organization: waitTimeoutSeconds === null
|
|
3573
|
+
? organization
|
|
3574
|
+
: await waitForFileOperation(api, organization.operation_id, {
|
|
3575
|
+
initialResult: organization,
|
|
3576
|
+
timeoutSeconds: waitTimeoutSeconds,
|
|
3577
|
+
}),
|
|
3578
|
+
};
|
|
3496
3579
|
}
|
|
3497
3580
|
} else if (action === "organize") {
|
|
3498
3581
|
requireConfirmation(options, "Starting a file organization run");
|
|
3499
|
-
|
|
3582
|
+
const organization = await api.request(`/files/${resourcePath(assetId || option(options, "id", { required: true }))}:organize`, {
|
|
3500
3583
|
method: "POST",
|
|
3501
3584
|
headers: options["caller-model"] ? { "x-corvio-caller-model": String(options["caller-model"]) } : {},
|
|
3502
3585
|
body: fileOrganizationBody(options),
|
|
3503
3586
|
});
|
|
3587
|
+
result = waitTimeoutSeconds === null
|
|
3588
|
+
? organization
|
|
3589
|
+
: await waitForFileOperation(api, organization.operation_id, {
|
|
3590
|
+
initialResult: organization,
|
|
3591
|
+
timeoutSeconds: waitTimeoutSeconds,
|
|
3592
|
+
});
|
|
3504
3593
|
} else if (action === "operation") {
|
|
3505
|
-
|
|
3594
|
+
const operationId = assetId || option(options, "id", { required: true });
|
|
3595
|
+
result = waitTimeoutSeconds === null
|
|
3596
|
+
? await api.request(`/file-operations/${resourcePath(operationId)}`)
|
|
3597
|
+
: await waitForFileOperation(api, operationId, { timeoutSeconds: waitTimeoutSeconds });
|
|
3506
3598
|
} else if (action === "resume" || action === "cancel") {
|
|
3507
3599
|
const operationId = assetId || option(options, "id", { required: true });
|
|
3508
3600
|
requireConfirmation(
|
|
3509
3601
|
options,
|
|
3510
3602
|
`${action === "resume" ? "Resuming" : "Cancelling"} this file organization operation`,
|
|
3511
3603
|
);
|
|
3512
|
-
|
|
3604
|
+
const operation = await api.request(`/file-operations/${resourcePath(operationId)}:${action}`, {
|
|
3513
3605
|
method: "POST",
|
|
3514
3606
|
retrySafe: true,
|
|
3515
3607
|
});
|
|
3608
|
+
result = action === "resume" && waitTimeoutSeconds !== null
|
|
3609
|
+
? await waitForFileOperation(api, operationId, {
|
|
3610
|
+
initialResult: operation,
|
|
3611
|
+
timeoutSeconds: waitTimeoutSeconds,
|
|
3612
|
+
})
|
|
3613
|
+
: operation;
|
|
3516
3614
|
} else if (action === "open") {
|
|
3517
3615
|
const targetId = assetId || option(options, "id", { required: true });
|
|
3518
3616
|
const target = `${String(process.env.CORVIO_APP_BASE || DEFAULT_APP_BASE).replace(/\/+$/, "")}/app/a/${resourcePath(targetId)}`;
|
package/dist/core.js
CHANGED