@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.
Files changed (2) hide show
  1. package/dist/cli.js +46 -8
  2. 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.6";
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\nAgent creation and rotation print the cvg_ secret once.`,
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(option(options, "document-id", { required: true }))}/comments`, {
855
+ result = await api.request(`/documents/${resourcePath(documentId)}/comments`, {
822
856
  method: "POST",
823
857
  body: {
824
- body: option(options, "body", { required: true }),
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(option(options, "document-id", { required: true }))}/comments/${resourcePath(threadId)}/replies`, {
881
+ result = await api.request(`/documents/${resourcePath(documentId)}/comments/${resourcePath(threadId)}/replies`, {
845
882
  method: "POST",
846
883
  body: {
847
- body: option(options, "body", { required: true }),
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"] } : {}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corvio/cli",
3
- "version": "0.1.0-beta.6",
3
+ "version": "0.1.0-beta.7",
4
4
  "description": "Official Corvio Workspace CLI for questions, knowledge search, documents, and Agent workflows.",
5
5
  "type": "module",
6
6
  "bin": {