@corvio/cli 0.1.0-beta.6 → 0.1.0-beta.7
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/dist/cli.js +46 -8
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
writeTextFile,
|
|
36
36
|
} from "./core.js";
|
|
37
37
|
|
|
38
|
-
const VERSION = "0.1.0-beta.
|
|
38
|
+
const VERSION = "0.1.0-beta.7";
|
|
39
39
|
const DEFAULT_API_BASE = "https://api.corvio.ai/v1";
|
|
40
40
|
const DEFAULT_APP_BASE = "https://corvio.ai";
|
|
41
41
|
const USER_AGENT = `corvio-cli/${VERSION}`;
|
|
@@ -64,6 +64,7 @@ const COMMAND_OPTIONS = Object.freeze({
|
|
|
64
64
|
"capabilities:": [],
|
|
65
65
|
"ask:": ["prompt", "conversation-id", "sources", "allow-actions", "context-file", "idempotency-key"],
|
|
66
66
|
"agents:list": ["include-revoked"],
|
|
67
|
+
"agents:connect": ["handle", "avatar-url", "provider", "permissions"],
|
|
67
68
|
"agents:create": ["handle", "display-name", "avatar-url", "provider", "permissions"],
|
|
68
69
|
"agents:update": ["id", "display-name", "avatar-url", "status", "permissions"],
|
|
69
70
|
"agents:rotate": ["id"],
|
|
@@ -112,7 +113,7 @@ Usage:
|
|
|
112
113
|
corvio workspaces list|use|current|create [id]
|
|
113
114
|
corvio capabilities
|
|
114
115
|
corvio ask --prompt <text> [--conversation-id <id>] [--allow-actions]
|
|
115
|
-
corvio agents list|create|update|rotate [id]
|
|
116
|
+
corvio agents list|connect|create|update|rotate [id]
|
|
116
117
|
corvio agent claim|renew|complete|fail|comments|comment|reply|status|run [id]
|
|
117
118
|
corvio questions list|get [id]
|
|
118
119
|
corvio conversations list|get [id]
|
|
@@ -139,7 +140,7 @@ const COMMAND_HELP = Object.freeze({
|
|
|
139
140
|
workspaces: `Usage:\n corvio workspaces list\n corvio workspaces use <workspace-id>\n corvio workspaces current\n corvio workspaces create --name <name> [--kind personal|team]\n\nWorkspace status and blocked capability reasons are returned with each item.`,
|
|
140
141
|
capabilities: `Usage: corvio capabilities [--json]\n\nShow live API resources, principal scopes, selected Workspace status, and CLI compatibility.`,
|
|
141
142
|
ask: `Usage: corvio ask --prompt <text> [--conversation-id <id>] [--sources workspace,web,memory] [--allow-actions] [--context-file <json>] [--idempotency-key <key>]`,
|
|
142
|
-
agents: `Usage:\n corvio agents list\n corvio agents create --handle <handle> --display-name <name> [--provider codex|claude_code|custom] [--permissions read,comment,edit]\n corvio agents update <id> [--display-name <name>] [--status active|paused|revoked] [--permissions <list>]\n corvio agents rotate <id>\n\
|
|
143
|
+
agents: `Usage:\n corvio agents list\n corvio agents connect --handle <handle> [--provider codex|claude_code|custom] [--permissions read,comment,edit]\n corvio agents create --handle <handle> --display-name <name> [--provider codex|claude_code|custom] [--permissions read,comment,edit]\n corvio agents update <id> [--display-name <name>] [--status active|paused|revoked] [--permissions <list>]\n corvio agents rotate <id>\n\n'connect' explicitly creates a separate cvg_ Agent principal after user authentication and leaves naming pending in Workspace. It never converts the human cvu_ login into an Agent. Creation and rotation print the cvg_ secret once.`,
|
|
143
144
|
agent: `Usage:\n corvio agent claim [--worker-id <id>] [--wait-seconds <0-30>]\n corvio agent renew <event-id> --lease-token <token> [--lease-seconds <30-900>]\n corvio agent complete <event-id> --lease-token <token> [--result-file <json>]\n corvio agent fail <event-id> --lease-token <token> --error <message>\n corvio agent comments --document-id <id>\n corvio agent comment --document-id <id> --body <text> [--selection-file <json>]\n corvio agent reply <thread-id> --document-id <id> --body <text>\n corvio agent status <thread-id> --document-id <id> --status open|resolved\n corvio agent run --handler <executable> [--once]\n\nThe runner leases durable events and renews its lease while work is active. The handler reads event JSON from stdin and returns {"instruction":"...","reply":"..."}; Corvio Query owns document changes and returns the durable receipt.`,
|
|
144
145
|
questions: `Usage:\n corvio questions list [--limit <n>] [--cursor <cursor>] [--conversation-id <id>]\n corvio questions get <question-id>`,
|
|
145
146
|
conversations: `Usage:\n corvio conversations list [--limit <n>] [--cursor <cursor>]\n corvio conversations get <conversation-id>`,
|
|
@@ -550,6 +551,17 @@ async function agents(options, action, id) {
|
|
|
550
551
|
let result;
|
|
551
552
|
if (action === "list") {
|
|
552
553
|
result = await api.request("/agents", { query: { include_revoked: options["include-revoked"] || undefined } });
|
|
554
|
+
} else if (action === "connect") {
|
|
555
|
+
result = await api.request("/agents", {
|
|
556
|
+
method: "POST",
|
|
557
|
+
body: {
|
|
558
|
+
handle: option(options, "handle", { required: true }),
|
|
559
|
+
avatar_url: options["avatar-url"] || null,
|
|
560
|
+
provider: options.provider || "custom",
|
|
561
|
+
permissions: listOption(options, "permissions", ["read", "comment"]),
|
|
562
|
+
pending_naming: true,
|
|
563
|
+
},
|
|
564
|
+
});
|
|
553
565
|
} else if (action === "create") {
|
|
554
566
|
result = await api.request("/agents", {
|
|
555
567
|
method: "POST",
|
|
@@ -574,7 +586,7 @@ async function agents(options, action, id) {
|
|
|
574
586
|
const agentId = id || option(options, "id", { required: true });
|
|
575
587
|
result = await api.request(`/agents/${resourcePath(agentId)}/credentials:rotate`, { method: "POST" });
|
|
576
588
|
} else {
|
|
577
|
-
throw new CliError("agents action must be list, create, update, or rotate.");
|
|
589
|
+
throw new CliError("agents action must be list, connect, create, update, or rotate.");
|
|
578
590
|
}
|
|
579
591
|
writeResult(result, { json: options.json });
|
|
580
592
|
}
|
|
@@ -712,10 +724,12 @@ async function processClaimedAgentEvent(api, event, options) {
|
|
|
712
724
|
let commentEntryId = null;
|
|
713
725
|
if (documentId && threadId) {
|
|
714
726
|
const reply = String(decision.reply || question.answer || "Completed the requested review.").trim().slice(0, 12_000);
|
|
727
|
+
const mentionTargets = await resolveAgentMentionTargets(api, documentId, reply);
|
|
715
728
|
const thread = await api.request(`/documents/${resourcePath(documentId)}/comments/${resourcePath(threadId)}/replies`, {
|
|
716
729
|
method: "POST",
|
|
717
730
|
body: {
|
|
718
731
|
body: reply,
|
|
732
|
+
mention_targets: mentionTargets,
|
|
719
733
|
entry_point: "external_agent_runner",
|
|
720
734
|
source_event_id: event.id,
|
|
721
735
|
source_event_lease_token: leaseToken,
|
|
@@ -773,6 +787,24 @@ async function runAgent(options) {
|
|
|
773
787
|
}
|
|
774
788
|
}
|
|
775
789
|
|
|
790
|
+
async function resolveAgentMentionTargets(api, documentId, body) {
|
|
791
|
+
const aliases = Array.from(String(body || "").matchAll(/(?:^|\s)@([a-z0-9][a-z0-9._-]{0,63})/gi))
|
|
792
|
+
.map((match) => String(match[1] || "").toLowerCase());
|
|
793
|
+
if (!aliases.length) return [];
|
|
794
|
+
const response = await api.request(`/documents/${resourcePath(documentId)}/mention-candidates`);
|
|
795
|
+
const byHandle = new Map((Array.isArray(response?.data) ? response.data : []).map((candidate) => [
|
|
796
|
+
String(candidate.handle || "").toLowerCase(),
|
|
797
|
+
candidate,
|
|
798
|
+
]));
|
|
799
|
+
const seen = new Set();
|
|
800
|
+
return aliases.flatMap((alias) => {
|
|
801
|
+
const candidate = byHandle.get(alias);
|
|
802
|
+
if (!candidate?.id || seen.has(candidate.id)) return [];
|
|
803
|
+
seen.add(candidate.id);
|
|
804
|
+
return [{ kind: "agent", principal_id: candidate.id, alias: candidate.handle }];
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
|
|
776
808
|
async function agentCommand(options, action, id) {
|
|
777
809
|
if (action === "run") return runAgent(options);
|
|
778
810
|
const api = agentClient(options);
|
|
@@ -815,13 +847,16 @@ async function agentCommand(options, action, id) {
|
|
|
815
847
|
} else if (action === "comments") {
|
|
816
848
|
result = await api.request(`/documents/${resourcePath(option(options, "document-id", { required: true }))}/comments`);
|
|
817
849
|
} else if (action === "comment") {
|
|
850
|
+
const documentId = option(options, "document-id", { required: true });
|
|
851
|
+
const body = option(options, "body", { required: true });
|
|
818
852
|
const selection = options["selection-file"]
|
|
819
853
|
? await readJsonObject(options["selection-file"], "--selection-file")
|
|
820
854
|
: { target_scope: "document" };
|
|
821
|
-
result = await api.request(`/documents/${resourcePath(
|
|
855
|
+
result = await api.request(`/documents/${resourcePath(documentId)}/comments`, {
|
|
822
856
|
method: "POST",
|
|
823
857
|
body: {
|
|
824
|
-
body
|
|
858
|
+
body,
|
|
859
|
+
mention_targets: await resolveAgentMentionTargets(api, documentId, body),
|
|
825
860
|
selection,
|
|
826
861
|
entry_point: "external_agent_cli",
|
|
827
862
|
start_new_chain: Boolean(options["start-new-chain"]),
|
|
@@ -829,6 +864,8 @@ async function agentCommand(options, action, id) {
|
|
|
829
864
|
});
|
|
830
865
|
} else if (action === "reply") {
|
|
831
866
|
const threadId = id || option(options, "id", { required: true });
|
|
867
|
+
const documentId = option(options, "document-id", { required: true });
|
|
868
|
+
const bodyText = option(options, "body", { required: true });
|
|
832
869
|
const hasSourceEventId = Boolean(options["source-event-id"]);
|
|
833
870
|
const hasSourceEventLease = Boolean(options["source-event-lease-token"]);
|
|
834
871
|
if (hasSourceEventId !== hasSourceEventLease) {
|
|
@@ -841,10 +878,11 @@ async function agentCommand(options, action, id) {
|
|
|
841
878
|
code: "agent_reply_source_conflict",
|
|
842
879
|
});
|
|
843
880
|
}
|
|
844
|
-
result = await api.request(`/documents/${resourcePath(
|
|
881
|
+
result = await api.request(`/documents/${resourcePath(documentId)}/comments/${resourcePath(threadId)}/replies`, {
|
|
845
882
|
method: "POST",
|
|
846
883
|
body: {
|
|
847
|
-
body:
|
|
884
|
+
body: bodyText,
|
|
885
|
+
mention_targets: await resolveAgentMentionTargets(api, documentId, bodyText),
|
|
848
886
|
entry_point: "external_agent_cli_reply",
|
|
849
887
|
...(options["source-event-id"] ? { source_event_id: options["source-event-id"] } : {}),
|
|
850
888
|
...(options["source-event-lease-token"] ? { source_event_lease_token: options["source-event-lease-token"] } : {}),
|