@corvio/cli 0.1.0-beta.32 → 0.1.0-beta.34
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 +7 -3
- package/dist/cli.js +199 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,6 +15,8 @@ corvio files get <asset_id> --content --json
|
|
|
15
15
|
corvio files organize <asset_id> --instruction 'Create a reusable decision brief' --yes --json
|
|
16
16
|
corvio files operation <operation_id> --json
|
|
17
17
|
corvio files resume <operation_id> --yes --json
|
|
18
|
+
corvio docs read <workspace_id/document_id> --mode auto --json
|
|
19
|
+
corvio docs patch <workspace_id/document_id> --input ./patch.json --operation-id <id> --yes --json
|
|
18
20
|
corvio docs table-read <workspace_id/document_id> --limit 25 --json
|
|
19
21
|
corvio docs table-mutate <workspace_id/document_id> --input ./table-change.json --change-summary 'Updated owner and due date' --yes --json
|
|
20
22
|
corvio sync init --dir ./knowledge --root-node-id <node_id> --json
|
|
@@ -24,15 +26,17 @@ corvio update check --json
|
|
|
24
26
|
When no environment key is configured, run `corvio auth login`. Login creates one user-level `cvu_` control-plane credential; it does not freeze the browser's current Workspace. Run `corvio agents connect --project .` from the project you want to expose. The command verifies the selected Codex, Claude Code, or Copilot host before server mutation, then idempotently creates or restores the Agent for that provider/device/project binding, grants current/future Workspace coverage under live membership/role and ACL limits, saves the one-time `cvg_` in a `0600` multi-binding registry, and starts that project's listener. `corvio collaboration status` then checks local foreground prerequisites and reports package freshness, contract compatibility, installation ownership, every discoverable copy, and the fact that host loading is not observable. A listener receives inbound `@Agent` work; it does not make an unrelated foreground coding session collaborate automatically. Another project gets another Agent. Ordinary data commands prefer the binding whose root contains the current directory, then a locally confirmed selection, the account selection, the personal default, or one authorized candidate. They ask only on real ambiguity. Use `corvio workspaces use`, `--workspace`, and `--agent` as explicit routing/reproducibility controls. Legacy Workspace-bound `cvk_`, `cvg_`, and version-1 credential files remain compatible and are never widened. Local sync stores only credential-free handles and revision/hash baselines in `.corvio/state.json`; Markdown lives below `corvio_docs/`, and conflicts require explicit resolution. `corvio capabilities` reads only Corvio API capability and compatibility facts, so discovery remains usable in hosts that deny npm registry access. `corvio update check` is the explicit registry-backed version check; it never self-installs. See [the Corvio CLI guide](https://corvio.ai/developers/cli) for the full command and receipt contract.
|
|
25
27
|
|
|
26
28
|
CLI and Skill updates are independent. `corvio update check` checks the CLI package only. `corvio collaboration status` detects a missing,
|
|
27
|
-
incompatible, compatible-but-not-current, or conflicting local Skill, but never mutates host directories.
|
|
28
|
-
|
|
29
|
+
incompatible, compatible-but-not-current, or conflicting local Skill, but never mutates host directories. Non-current receipts include one
|
|
30
|
+
compact Agent notice and a source-aware action; current copies stay quiet. For standalone Skill refreshes,
|
|
31
|
+
the command pins the verified installer, selects exactly one provider, preserves project/global scope, and returns a verification command.
|
|
32
|
+
Use `corvio collaboration status --provider workbuddy --json --no-input` to inspect WorkBuddy's manual copy at
|
|
29
33
|
`~/.workbuddy/skills/corvio-operate-workspace/`; this does not prove which bytes a running WorkBuddy conversation loaded. The canonical
|
|
30
34
|
website ZIP is a static local copy and is not update-tracked by `npx skills update`; reinstall from the same source and scope, then start a
|
|
31
35
|
fresh host session. Until a reviewed WorkBuddy marketplace listing is live, a WorkBuddy upload is an unmanaged manual install and cannot
|
|
32
36
|
auto-update from Corvio. Remote MCP changes are server-delivered and normally need only a refreshed host session unless new OAuth scopes
|
|
33
37
|
require reauthorization.
|
|
34
38
|
|
|
35
|
-
The CLI rejects unknown/duplicate options and malformed integer bounds before network access. Normal API calls have a bounded timeout (`CORVIO_REQUEST_TIMEOUT_MS`, maximum ten minutes); only reads, explicit idempotency contracts, revision guards, and other owner-declared safe operations retry automatically. Document commands accept both bare document IDs and canonical `workspace_id/document_id` handles; a canonical handle that disagrees with the selected Workspace fails before remote access, and successful reads return `canonical_id` for direct reuse. Document updates preflight the current revision when `--expected-revision` is omitted. `docs table-read` returns a bounded stable-ID projection; `docs table-mutate` accepts a JSON payload for at most 50 cell updates or row appends and requires the fetched revision, while formulas, styles, structure, sorting, and semantic transformations remain `corvio ask --allow-actions` work. When the executing principal is a connected Agent, document and table mutations also require `--change-summary`, create a visible document-level comment after the guarded update, and return its receipt; a comment failure is reported as a partial effect rather than silent success. When a Corvio document or comment supplied the task, use `corvio agent closeout` to return the verified outcome, optionally resolve the thread, and read both document and thread back. Downloads, uploads, and Markdown pulls verify SHA-256 receipts before replacing local files; local writes are atomic, remote default filenames cannot escape the current directory, and Sync refuses symbolic-link traversal while checkpointing each successful push.
|
|
39
|
+
The CLI rejects unknown/duplicate options and malformed integer bounds before network access. Normal API calls have a bounded timeout (`CORVIO_REQUEST_TIMEOUT_MS`, maximum ten minutes); only reads, explicit idempotency contracts, revision guards, and other owner-declared safe operations retry automatically. Document commands accept both bare document IDs and canonical `workspace_id/document_id` handles; a canonical handle that disagrees with the selected Workspace fails before remote access, and successful reads return `canonical_id` for direct reuse. `docs read --mode auto` returns a complete small Page or a large-Page overview, then supports exact section, line-range, literal-search, and full projections. `docs patch` applies 1–20 exact non-overlapping L# replacements at the fetched revision and returns a compact readback instead of replaying untouched content. `docs get --output` keeps compatibility full-body download but omits the body from stdout; create/update request compact mutation receipts. Document updates preflight only a bounded overview for the current revision when `--expected-revision` is omitted. `docs table-read` returns a bounded stable-ID projection; `docs table-mutate` accepts a JSON payload for at most 50 cell updates or row appends and requires the fetched revision, while formulas, styles, structure, sorting, and semantic transformations remain `corvio ask --allow-actions` work. When the executing principal is a connected Agent, document and table mutations also require `--change-summary`, create a visible document-level comment after the guarded update, and return its receipt; a comment failure is reported as a partial effect rather than silent success. When a Corvio document or comment supplied the task, use `corvio agent closeout` to return the verified outcome, optionally resolve the thread, and read both document and thread back. Downloads, uploads, and Markdown pulls verify SHA-256 receipts before replacing local files; local writes are atomic, remote default filenames cannot escape the current directory, and Sync refuses symbolic-link traversal while checkpointing each successful push.
|
|
36
40
|
|
|
37
41
|
For `corvio ask`, pass the user's natural goal, complete decision-relevant context, and explicit constraints. Unless the user chose them,
|
|
38
42
|
do not invent taxonomy, titles, artifact counts, or Corvio's internal plan. Read the terminal Question receipt and use `artifact.url` or
|
package/dist/cli.js
CHANGED
|
@@ -39,14 +39,15 @@ 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.34";
|
|
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
|
|
49
|
+
const CORVIO_SKILL_ARCHIVE = "https://corvio.ai/developers/skills/corvio-operate-workspace/corvio-operate-workspace.zip";
|
|
50
|
+
const AGENT_SKILLS_INSTALLER_VERSION = "1.5.23";
|
|
50
51
|
const GLOBAL_OPTIONS = Object.freeze([
|
|
51
52
|
"api-base",
|
|
52
53
|
"workspace",
|
|
@@ -103,6 +104,11 @@ const COMMAND_OPTIONS = Object.freeze({
|
|
|
103
104
|
"search:": ["query", "limit", "page-id", "node-id"],
|
|
104
105
|
"docs:list": ["limit", "cursor", "lifecycle"],
|
|
105
106
|
"docs:get": ["id", "output"],
|
|
107
|
+
"docs:read": [
|
|
108
|
+
"id", "mode", "start-line", "end-line", "section-ref", "heading", "query",
|
|
109
|
+
"max-chars", "max-sections", "context-lines", "max-matches", "case-sensitive",
|
|
110
|
+
],
|
|
111
|
+
"docs:patch": ["id", "input", "operation-id", "change-summary", "yes"],
|
|
106
112
|
"docs:table-read": ["id", "table-id", "after-row-id", "limit"],
|
|
107
113
|
"docs:table-mutate": ["id", "input", "operation-id", "change-summary", "yes"],
|
|
108
114
|
"docs:create": ["title", "file", "markdown", "parent-node-id", "idempotency-key"],
|
|
@@ -151,7 +157,7 @@ Usage:
|
|
|
151
157
|
corvio questions list|get [id]
|
|
152
158
|
corvio conversations list|get [id]
|
|
153
159
|
corvio search <query>
|
|
154
|
-
corvio docs list|get|table-read|table-mutate|create|update|move|archive|restore|share|open [id]
|
|
160
|
+
corvio docs list|get|read|patch|table-read|table-mutate|create|update|move|archive|restore|share|open [id]
|
|
155
161
|
corvio projects list|create
|
|
156
162
|
corvio files list|get|download|upload|organize|operation|resume|cancel|open [id]
|
|
157
163
|
corvio sync init|status|plan|pull|push|resolve
|
|
@@ -173,14 +179,14 @@ const COMMAND_HELP = Object.freeze({
|
|
|
173
179
|
auth: `Usage: corvio auth login|status|logout\n\nAuthenticate with a user-level device link, inspect the current principal, or revoke the stored credential.`,
|
|
174
180
|
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.`,
|
|
175
181
|
capabilities: `Usage: corvio capabilities [--json]\n\nShow live API resources, principal scopes, selected Workspace status, and CLI compatibility.`,
|
|
176
|
-
collaboration: `Usage:\n corvio collaboration status [--project <path>] [--provider codex|claude_code|copilot|workbuddy]\n\nCheck local Corvio prerequisites and every discoverable Corvio Skill copy.
|
|
182
|
+
collaboration: `Usage:\n corvio collaboration status [--project <path>] [--provider codex|claude_code|copilot|workbuddy]\n\nCheck local Corvio prerequisites and every discoverable Corvio Skill copy. Current copies stay quiet; non-current receipts include one compact Agent notice and a source-aware next action. Standalone refresh commands pin the verified installer, select exactly one provider, and preserve project/global scope. WorkBuddy inspection is read-only and never changes ~/.workbuddy. The CLI cannot prove that the current host task loaded a particular copy, or whether remote MCP or host memory is active.`,
|
|
177
183
|
ask: `Usage: corvio ask --prompt <text> [--file <path>] [--asset-ids <id,id>] [--conversation-id <id>] [--sources workspace,web,memory] [--allow-actions] [--processing-profile auto|economy|standard|deep] [--max-processing-profile economy|standard|deep] [--scan-mode auto|always|off] [--skills-extraction-mode auto|always|off] [--caller-model <host-model>] [--context-file <json>] [--idempotency-key <key>]\n\nPass the user's natural goal, complete decision-relevant context, and explicit constraints. Unless the user chose them, do not invent taxonomy, titles, artifact count, or Corvio's internal plan; Corvio chooses the cognitive structure and carriers. --file retains the selected local file, verifies its hash, and attaches the finalized Asset to this exact question. --asset-ids attaches already-retained Corvio Assets. Use --allow-actions when Corvio should create the Page, Spreadsheet, Presentation, Code, HTML Artifact, Memory, or qualifying Project Skill that best serves the result. A continuation handle is subject evidence, not necessarily the durable write destination: for a reusable pattern or method, resolve the fitting same-scope Memory or Skill owner before admitting or merging it. Read the terminal Question receipt and use artifact.url or links.primary_artifact verbatim; reader_output artifacts are deliverables, structure_container artifacts are hierarchy, and node_id is never a document URL. Upload alone is not evidence of interpretation. Skill extraction mode always requires --allow-actions and an evidence-backed decision, not forced Skill creation; answer-only questions may use auto or off.`,
|
|
178
184
|
agents: `Usage:\n corvio agents list\n corvio agents connect [--provider codex|claude_code|copilot] [--project <path>] [--permission-profile read_only|workspace_write|danger_full_access] [--trigger-policy owner_only|workspace_members] [--display-name <name>] [--recover-credential] [--no-listen]\n corvio agents create --handle <handle> --display-name <name> [--provider codex|claude_code|copilot|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' binds the current Git project (or --project path) to one stable personal Agent. Repeating it is idempotent; another project creates another Agent. It reports provider/CLI, listener, and local Skill prerequisites separately; run corvio collaboration status after installing or refreshing the Skill. The CLI cannot prove that the current host task loaded those surfaces. The default workspace_write profile is limited by the provider's native sandbox. owner_only is the safe trigger default. Secrets and absolute project paths stay local.`,
|
|
179
185
|
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 mentions --document-id <id> [--query <name>]\n corvio agent comments --document-id <id>\n corvio agent comment --document-id <id> --body <text> [--selection-file <json>] [--start-new-chain] [--idempotency-key <key>]\n corvio agent reply <thread-id> --document-id <id> --body <text> [--source-event-id <id> --source-event-lease-token <token>|--start-new-chain] [--idempotency-key <key>]\n corvio agent status <thread-id> --document-id <id> --status open|resolved\n corvio agent closeout --document-id <id> [--thread-id <id>] --body <verified-result> [--status open|resolved] [--idempotency-key <key>]\n corvio agent run [--provider codex|claude_code|copilot|custom] [--handler <executable>] [--agent <id>] [--once] [--processing-profile auto|economy|standard|deep] [--max-processing-profile economy|standard|deep] [--scan-mode auto|always|off] [--skills-extraction-mode auto|always|off] [--caller-model <host-model>]\n\nUse mentions before commenting when the target is uncertain; aliases resolve to stable user or Agent IDs and ambiguity fails closed. Use closeout when a Corvio document or comment owned the task: it returns the verified result to that surface and reads document/comments back. Agent-to-Agent comments require either a claimed source event or explicit --start-new-chain. The runner iteratively exchanges origin-scoped evidence with Corvio Query/Writer, then invokes the bound provider inside its local project. Local code changes use the recorded provider permission profile; complex Corvio document changes belong to Query/Writer. Provider children never receive Corvio credentials.`,
|
|
180
186
|
questions: `Usage:\n corvio questions list [--limit <n>] [--cursor <cursor>] [--conversation-id <id>]\n corvio questions get <question-id>`,
|
|
181
187
|
conversations: `Usage:\n corvio conversations list [--limit <n>] [--cursor <cursor>]\n corvio conversations get <conversation-id>`,
|
|
182
188
|
search: `Usage: corvio search <query> [--limit <n>] [--page-id <id>] [--node-id <id>]`,
|
|
183
|
-
docs: `Usage:\n corvio docs list [--limit <n>] [--cursor <cursor>] [--lifecycle active|archived]\n corvio docs get <id> [--output <path>]\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\
|
|
189
|
+
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.`,
|
|
184
190
|
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.`,
|
|
185
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>\n corvio files resume <operation-id> --yes\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. 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 'files operation' to reach terminal and inspect output_document plus skills_evaluation; always requires evaluation but may correctly return evaluated_no_qualifying_skill. Resume reuses the same durable operation after resolving its blocker; cancel is idempotent.`,
|
|
186
192
|
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>]`,
|
|
@@ -237,6 +243,8 @@ function validateInvocation(options, positionals) {
|
|
|
237
243
|
"questions:get",
|
|
238
244
|
"conversations:get",
|
|
239
245
|
"docs:get",
|
|
246
|
+
"docs:read",
|
|
247
|
+
"docs:patch",
|
|
240
248
|
"docs:table-read",
|
|
241
249
|
"docs:table-mutate",
|
|
242
250
|
"docs:update",
|
|
@@ -813,6 +821,58 @@ function collaborationRevisionAtLeast(actual, minimum) {
|
|
|
813
821
|
return true;
|
|
814
822
|
}
|
|
815
823
|
|
|
824
|
+
function skillInstallerAgent(provider) {
|
|
825
|
+
return {
|
|
826
|
+
codex: "codex",
|
|
827
|
+
claude_code: "claude-code",
|
|
828
|
+
copilot: "github-copilot",
|
|
829
|
+
}[provider] || null;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
function scopedSkillInstallCommand(provider, evaluated) {
|
|
833
|
+
const agent = skillInstallerAgent(provider);
|
|
834
|
+
if (!agent) return null;
|
|
835
|
+
const projectScoped = !evaluated.length || evaluated.some((item) => item.scope.startsWith("project_"));
|
|
836
|
+
const globalFlag = projectScoped ? "" : " --global";
|
|
837
|
+
return `npx --yes skills@${AGENT_SKILLS_INSTALLER_VERSION} add ${CORVIO_SKILL_ARCHIVE} --agent ${agent} --skill corvio-operate-workspace --yes${globalFlag}`;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
function collaborationAgentNotice(guidance) {
|
|
841
|
+
const status = guidance.package_status;
|
|
842
|
+
if (status === "current") return null;
|
|
843
|
+
if (status === "compatible_update_available") {
|
|
844
|
+
return {
|
|
845
|
+
code: "corvio_legacy_compatible",
|
|
846
|
+
message: `This host is using Corvio ${guidance.discovered_copies[0]?.release_version || guidance.discovered_copies[0]?.contract_revision || "legacy guidance"}; ${guidance.expected_release_version || guidance.expected_contract_version} is current. It may continue, but Beta feedback should identify this session as legacy.`,
|
|
847
|
+
continue_allowed: true,
|
|
848
|
+
recommended_action: guidance.install_command || guidance.update_action,
|
|
849
|
+
show_once_per_session: true,
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
if (status === "freshness_unverified") {
|
|
853
|
+
return {
|
|
854
|
+
code: "corvio_freshness_unverified",
|
|
855
|
+
message: `The loaded Corvio copy declares the current contract, but upstream package integrity could not be verified (${guidance.upstream_manifest_status}).`,
|
|
856
|
+
continue_allowed: true,
|
|
857
|
+
recommended_action: "Retry the status check before claiming this host is current; do not describe manifest retrieval failure as a stale install.",
|
|
858
|
+
show_once_per_session: true,
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
const messages = {
|
|
862
|
+
missing: "Corvio guidance is not installed in the effective host scope.",
|
|
863
|
+
multiple_copies_conflict: "Multiple effective Corvio copies disagree. Resolve the reported scopes before relying on the guidance.",
|
|
864
|
+
update_required: "The effective Corvio guidance is unsupported or differs from the official package.",
|
|
865
|
+
contract_unavailable: "The current Corvio collaboration contract could not be loaded.",
|
|
866
|
+
};
|
|
867
|
+
return {
|
|
868
|
+
code: `corvio_${status}`,
|
|
869
|
+
message: messages[status] || "Corvio host guidance is not ready.",
|
|
870
|
+
continue_allowed: false,
|
|
871
|
+
recommended_action: guidance.install_command || guidance.update_action || "Inspect the reported source and retry before continuing.",
|
|
872
|
+
show_once_per_session: true,
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
|
|
816
876
|
async function loadOfficialSkillManifest(liveContract) {
|
|
817
877
|
const manifestUrl = String(dictLike(dictLike(liveContract?.distribution).official_skill).manifest || "").trim();
|
|
818
878
|
if (!manifestUrl) return { status: "unavailable", manifest: {} };
|
|
@@ -959,6 +1019,23 @@ async function inspectCollaborationGuidance(provider, projectRoot, liveContract,
|
|
|
959
1019
|
const refreshAvailable = new Set([
|
|
960
1020
|
"missing", "compatible_update_available", "update_required", "multiple_copies_conflict",
|
|
961
1021
|
]).has(packageStatus);
|
|
1022
|
+
const pluginManaged = evaluated.some((item) => item.source === "plugin_cache");
|
|
1023
|
+
const installCommand = provider !== "workbuddy"
|
|
1024
|
+
&& refreshAvailable
|
|
1025
|
+
&& packageStatus !== "multiple_copies_conflict"
|
|
1026
|
+
&& !pluginManaged
|
|
1027
|
+
? scopedSkillInstallCommand(provider, evaluated)
|
|
1028
|
+
: null;
|
|
1029
|
+
let updateAction = null;
|
|
1030
|
+
if (provider === "workbuddy" && refreshAvailable) {
|
|
1031
|
+
updateAction = workbuddyAction || "Download the official Skill ZIP, replace it in WorkBuddy, then start a fresh conversation.";
|
|
1032
|
+
} else if (packageStatus === "multiple_copies_conflict") {
|
|
1033
|
+
updateAction = "Resolve the reported effective scopes explicitly; do not overwrite either copy by assumption.";
|
|
1034
|
+
} else if (pluginManaged && refreshAvailable) {
|
|
1035
|
+
const channel = provider === "codex" ? "codex_marketplace" : "claude_code_marketplace";
|
|
1036
|
+
updateAction = dictLike(dictLike(distribution.host_channels)[channel]).action
|
|
1037
|
+
|| "Use the host marketplace/plugin update flow, then start a fresh session.";
|
|
1038
|
+
}
|
|
962
1039
|
return {
|
|
963
1040
|
status,
|
|
964
1041
|
package_status: packageStatus,
|
|
@@ -979,12 +1056,10 @@ async function inspectCollaborationGuidance(provider, projectRoot, liveContract,
|
|
|
979
1056
|
current_scopes: current.map((item) => item.scope),
|
|
980
1057
|
compatible_scopes: compatible.map((item) => item.scope),
|
|
981
1058
|
discovered_copies: found,
|
|
982
|
-
install_command:
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
? workbuddyAction || "Download the official Skill ZIP, replace it in WorkBuddy, then start a fresh conversation."
|
|
987
|
-
: null,
|
|
1059
|
+
install_command: installCommand,
|
|
1060
|
+
install_scope: installCommand ? (installCommand.endsWith(" --global") ? "global" : "project") : null,
|
|
1061
|
+
update_action: updateAction,
|
|
1062
|
+
verification_command: refreshAvailable ? `corvio collaboration status --provider ${provider} --project . --json --no-input` : null,
|
|
988
1063
|
};
|
|
989
1064
|
}
|
|
990
1065
|
|
|
@@ -1022,9 +1097,13 @@ async function collaborationStatus(options) {
|
|
|
1022
1097
|
if (!credential && requiresProjectAgent) nextActions.push(`corvio agents connect --provider ${provider} --project .`);
|
|
1023
1098
|
if (guidance.install_command) nextActions.push(guidance.install_command);
|
|
1024
1099
|
if (guidance.update_action) nextActions.push(guidance.update_action);
|
|
1100
|
+
if ((guidance.install_command || guidance.update_action) && guidance.verification_command) {
|
|
1101
|
+
nextActions.push(guidance.verification_command);
|
|
1102
|
+
}
|
|
1025
1103
|
if (!serverVersion) nextActions.push("corvio update check --json");
|
|
1026
1104
|
const localPrerequisitesReady = status === "ready";
|
|
1027
1105
|
const hostIntegration = dictLike(liveContract.host_integration);
|
|
1106
|
+
const agentNotice = collaborationAgentNotice(guidance);
|
|
1028
1107
|
writeResult({
|
|
1029
1108
|
status,
|
|
1030
1109
|
local_prerequisites_ready: localPrerequisitesReady,
|
|
@@ -1063,6 +1142,7 @@ async function collaborationStatus(options) {
|
|
|
1063
1142
|
? hostIntegration.decision_points
|
|
1064
1143
|
: [],
|
|
1065
1144
|
},
|
|
1145
|
+
...(agentNotice ? { agent_notice: agentNotice } : {}),
|
|
1066
1146
|
next_actions: nextActions,
|
|
1067
1147
|
}, { json: options.json });
|
|
1068
1148
|
}
|
|
@@ -2904,8 +2984,108 @@ async function docs(options, action, id) {
|
|
|
2904
2984
|
};
|
|
2905
2985
|
}
|
|
2906
2986
|
if (options.output) {
|
|
2907
|
-
|
|
2908
|
-
|
|
2987
|
+
const markdown = String(result.markdown || "");
|
|
2988
|
+
await writeTextFile(options.output, markdown);
|
|
2989
|
+
const { markdown: _omittedMarkdown, ...metadata } = result;
|
|
2990
|
+
result = {
|
|
2991
|
+
...metadata,
|
|
2992
|
+
output: options.output,
|
|
2993
|
+
body_returned: false,
|
|
2994
|
+
written_chars: markdown.length,
|
|
2995
|
+
content_sha256: createHash("sha256").update(markdown).digest("hex"),
|
|
2996
|
+
};
|
|
2997
|
+
}
|
|
2998
|
+
} else if (action === "read") {
|
|
2999
|
+
const targetId = resolveDocumentId(documentId, selection);
|
|
3000
|
+
const mode = String(options.mode || "auto").trim().toLowerCase().replaceAll("-", "_");
|
|
3001
|
+
if (!new Set(["auto", "overview", "line_range", "section", "search", "full"]).has(mode)) {
|
|
3002
|
+
throw new CliError("--mode must be auto, overview, line-range, section, search, or full.", {
|
|
3003
|
+
code: "document_read_mode_invalid",
|
|
3004
|
+
});
|
|
3005
|
+
}
|
|
3006
|
+
result = await api.request(`/documents/${resourcePath(targetId)}/content`, {
|
|
3007
|
+
query: {
|
|
3008
|
+
mode,
|
|
3009
|
+
start_line: options["start-line"] === undefined
|
|
3010
|
+
? undefined
|
|
3011
|
+
: numberOption(options, "start-line", undefined, { minimum: 1, maximum: 2_000_000 }),
|
|
3012
|
+
end_line: options["end-line"] === undefined
|
|
3013
|
+
? undefined
|
|
3014
|
+
: numberOption(options, "end-line", undefined, { minimum: 1, maximum: 2_000_000 }),
|
|
3015
|
+
section_ref: options["section-ref"] || undefined,
|
|
3016
|
+
heading: options.heading || undefined,
|
|
3017
|
+
query: options.query || undefined,
|
|
3018
|
+
max_chars: numberOption(options, "max-chars", 6000, { minimum: 200, maximum: 60000 }),
|
|
3019
|
+
max_sections: numberOption(options, "max-sections", 240, { minimum: 1, maximum: 400 }),
|
|
3020
|
+
context_lines: numberOption(options, "context-lines", 2, { minimum: 0, maximum: 12 }),
|
|
3021
|
+
max_matches: numberOption(options, "max-matches", 12, { minimum: 1, maximum: 30 }),
|
|
3022
|
+
case_sensitive: Boolean(options["case-sensitive"]),
|
|
3023
|
+
},
|
|
3024
|
+
});
|
|
3025
|
+
if (executionIdentity === "agent") {
|
|
3026
|
+
result = {
|
|
3027
|
+
...result,
|
|
3028
|
+
collaboration_follow_up: "If this document or one of its comments owns the task, return verified results to the originating collaboration surface after the work. A read-only citation needs no ceremonial comment.",
|
|
3029
|
+
};
|
|
3030
|
+
}
|
|
3031
|
+
} else if (action === "patch") {
|
|
3032
|
+
requireConfirmation(options, "Patching document line ranges");
|
|
3033
|
+
const targetId = resolveDocumentId(documentId, selection);
|
|
3034
|
+
const payload = await readJsonObject(option(options, "input", { required: true }), "--input");
|
|
3035
|
+
const changeSummary = String(options["change-summary"] || "").trim();
|
|
3036
|
+
if (executionIdentity === "agent" && !changeSummary) {
|
|
3037
|
+
throw new CliError(
|
|
3038
|
+
"Agent document patches require --change-summary so collaborators can see what changed and why.",
|
|
3039
|
+
{ code: "agent_document_change_summary_required" },
|
|
3040
|
+
);
|
|
3041
|
+
}
|
|
3042
|
+
const operationId = String(options["operation-id"] || payload.operation_id || randomUUID());
|
|
3043
|
+
result = await api.request(`/documents/${resourcePath(targetId)}/content`, {
|
|
3044
|
+
method: "PATCH",
|
|
3045
|
+
retrySafe: true,
|
|
3046
|
+
body: { ...payload, operation_id: operationId },
|
|
3047
|
+
});
|
|
3048
|
+
if (executionIdentity === "agent" && result?.status !== "no_op") {
|
|
3049
|
+
const commentIdempotencyKey = `document-patch:${createHash("sha256")
|
|
3050
|
+
.update(JSON.stringify({ document_id: targetId, operation_id: operationId, body: changeSummary }))
|
|
3051
|
+
.digest("hex")}`;
|
|
3052
|
+
try {
|
|
3053
|
+
const comment = await api.request(`/documents/${resourcePath(targetId)}/comments`, {
|
|
3054
|
+
method: "POST",
|
|
3055
|
+
headers: { "idempotency-key": commentIdempotencyKey },
|
|
3056
|
+
body: {
|
|
3057
|
+
body: changeSummary,
|
|
3058
|
+
mention_targets: [],
|
|
3059
|
+
selection: { target_scope: "document" },
|
|
3060
|
+
entry_point: "external_agent_cli_document_line_patch",
|
|
3061
|
+
start_new_chain: true,
|
|
3062
|
+
},
|
|
3063
|
+
});
|
|
3064
|
+
const entry = Array.isArray(comment?.entries) ? comment.entries.at(-1) : null;
|
|
3065
|
+
result = {
|
|
3066
|
+
...result,
|
|
3067
|
+
change_comment: {
|
|
3068
|
+
thread_id: comment?.id || null,
|
|
3069
|
+
entry_id: entry?.id || null,
|
|
3070
|
+
body: changeSummary,
|
|
3071
|
+
},
|
|
3072
|
+
};
|
|
3073
|
+
} catch (error) {
|
|
3074
|
+
throw new CliError(
|
|
3075
|
+
"The line patch succeeded, but its required change comment could not be created. Add the comment before reporting completion.",
|
|
3076
|
+
{
|
|
3077
|
+
code: "document_patched_comment_failed",
|
|
3078
|
+
exitCode: error instanceof CliError ? error.exitCode : EXIT.REMOTE,
|
|
3079
|
+
status: error instanceof CliError ? error.status : null,
|
|
3080
|
+
details: {
|
|
3081
|
+
document_id: targetId,
|
|
3082
|
+
operation_id: operationId,
|
|
3083
|
+
mutation: result,
|
|
3084
|
+
recovery_command: `corvio agent comment --document-id ${targetId} --body <change-summary> --start-new-chain --idempotency-key ${commentIdempotencyKey}`,
|
|
3085
|
+
},
|
|
3086
|
+
},
|
|
3087
|
+
);
|
|
3088
|
+
}
|
|
2909
3089
|
}
|
|
2910
3090
|
} else if (action === "table-read") {
|
|
2911
3091
|
const targetId = resolveDocumentId(documentId, selection);
|
|
@@ -2980,6 +3160,7 @@ async function docs(options, action, id) {
|
|
|
2980
3160
|
const markdown = options.file ? await readTextFile(options.file) : String(options.markdown || "");
|
|
2981
3161
|
result = await api.request("/documents", {
|
|
2982
3162
|
method: "POST",
|
|
3163
|
+
query: { response_mode: "compact" },
|
|
2983
3164
|
headers: { "idempotency-key": idempotencyKey(options) },
|
|
2984
3165
|
body: {
|
|
2985
3166
|
title: option(options, "title", { required: true }),
|
|
@@ -3008,7 +3189,9 @@ async function docs(options, action, id) {
|
|
|
3008
3189
|
if (options["expected-revision"] !== undefined) {
|
|
3009
3190
|
expectedRevision = numberOption(options, "expected-revision", undefined, { minimum: 0 });
|
|
3010
3191
|
} else {
|
|
3011
|
-
const current = await api.request(`/documents/${resourcePath(targetId)}
|
|
3192
|
+
const current = await api.request(`/documents/${resourcePath(targetId)}/content`, {
|
|
3193
|
+
query: { mode: "overview", max_chars: 1000, max_sections: 1 },
|
|
3194
|
+
});
|
|
3012
3195
|
if (!Number.isSafeInteger(current?.content_revision) || current.content_revision < 0) {
|
|
3013
3196
|
throw new CliError("Corvio did not return a valid document content revision.", {
|
|
3014
3197
|
code: "document_revision_missing",
|
|
@@ -3019,6 +3202,7 @@ async function docs(options, action, id) {
|
|
|
3019
3202
|
}
|
|
3020
3203
|
result = await api.request(`/documents/${resourcePath(targetId)}`, {
|
|
3021
3204
|
method: "PUT",
|
|
3205
|
+
query: { response_mode: "compact" },
|
|
3022
3206
|
body: {
|
|
3023
3207
|
...(options.title !== undefined ? { title: options.title } : {}),
|
|
3024
3208
|
...(markdown !== undefined ? { markdown } : {}),
|
|
@@ -3103,7 +3287,7 @@ async function docs(options, action, id) {
|
|
|
3103
3287
|
const opened = options["no-input"] ? false : await openBrowser(target);
|
|
3104
3288
|
result = { document_id: targetId, url: target, opened };
|
|
3105
3289
|
} else {
|
|
3106
|
-
throw new CliError("docs action must be list, get, table-read, table-mutate, create, update, move, archive, restore, share, or open.");
|
|
3290
|
+
throw new CliError("docs action must be list, get, read, patch, table-read, table-mutate, create, update, move, archive, restore, share, or open.");
|
|
3107
3291
|
}
|
|
3108
3292
|
if (!new Set(["list", "create"]).has(action)) {
|
|
3109
3293
|
result = withCanonicalDocumentId(result, selection, resolveDocumentId(documentId, selection));
|