@caveman-ai/cloud 0.1.0-rc.30 → 0.1.0-rc.33
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 +5 -3
- package/bin/ci.mjs +2 -2
- package/bin/cvm.mjs +14 -1
- package/dist/cloud-client.mjs +59 -36
- package/dist/cloud-mcp.mjs +34 -34
- package/dist/criterion-registry.json +80 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,12 +6,14 @@ Every Caveman Cloud operation from the terminal, plus the Cloud MCP server.
|
|
|
6
6
|
npx -y @caveman-ai/cloud@rc setup --project PROJECT_ID # installs cvm, signs in, connects your coding agents
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
`@rc` is the newest release; `latest`
|
|
9
|
+
`@rc` is the newest release; npm's `latest` tag lags behind it, so install `@rc`. `npm i -g @caveman-ai/cloud@rc` installs cvm by itself. When cvm and the server speak different API versions, the error (and `cvm doctor`) prints the exact install command: the server's release when it reports one, else `@rc`.
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
12
|
cvm login # browser sign-in; one sign-in for cvm and caveman
|
|
13
13
|
cvm projects list
|
|
14
|
-
cvm traces
|
|
14
|
+
cvm traces # the verbs in one family
|
|
15
|
+
cvm traces search --help # the flags one verb takes
|
|
16
|
+
cvm traces tail # new traces as they arrive (Ctrl-C stops)
|
|
15
17
|
cvm sql "SELECT model, count() FROM requests GROUP BY model"
|
|
16
18
|
cvm tools list # every operation this Cloud offers you
|
|
17
19
|
cvm mcp # Cloud MCP server over stdio
|
|
@@ -20,7 +22,7 @@ cvm mcp # Cloud MCP server over stdio
|
|
|
20
22
|
- **Sign-in.** `cvm login` signs in with the browser device flow: it prints a code and a link, opens the browser (`--no-browser` or `CAVE_NO_BROWSER=1` to skip) and waits for you to confirm. It stores the credential where `caveman login` does (the macOS Keychain, else `~/.caveman/credentials`), so either CLI's sign-in works for both; `cvm logout` signs both out. `--instance URL` (or `CAVE_API_URL`) signs in to a private install. In CI, set `CAVE_TOKEN` (and `CAVE_API_URL` for a private install).
|
|
21
23
|
- **Environment.** A flag wins over the environment, and the environment over the saved login: `CAVE_API_URL`, `CAVE_PROJECT_ID`, `CAVE_TOKEN`. The saved credential is only ever sent to the address it was saved with; another `CAVE_API_URL` needs its own `CAVE_TOKEN`.
|
|
22
24
|
- **Projects.** Use `--project UUID`, `CAVE_PROJECT_ID`, `cvm context bind` (writes `.caveman-cloud.json` in the repository) or the saved default.
|
|
23
|
-
- **Output.** JSON when piped, readable when on a terminal; `--format json|jsonl|table`.
|
|
25
|
+
- **Output.** JSON when piped, readable when on a terminal; `--format json|jsonl|table`. Help follows the same rule: `cvm`, `cvm <family>` and `cvm <family> <verb> --help` are screens on a terminal and JSON when piped, and a mistyped command names the nearest one.
|
|
24
26
|
- **Exit codes.** 0 ok · 1 request failed · 2 usage or invalid input (HTTP 400/422) · 3 signed out or forbidden (401/403) · 4 conflict (409) · 5 a comparison or gate failed · 6 timeout, still running or not enough data · 7 rate limited (429).
|
|
25
27
|
|
|
26
28
|
## Setup
|
package/bin/ci.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import {randomUUID} from 'node:crypto';
|
|
|
9
9
|
import {join} from 'node:path';
|
|
10
10
|
import {parseArgs} from 'node:util';
|
|
11
11
|
import {setTimeout as delay} from 'node:timers/promises';
|
|
12
|
-
import {CloudClient,CloudError,inertJSON,runCloudCLI} from '../dist/cloud-client.mjs';
|
|
12
|
+
import {CloudClient,CloudError,inertJSON,runCloudCLI,versionConflictMessage} from '../dist/cloud-client.mjs';
|
|
13
13
|
|
|
14
14
|
const MAX_REPORTS=20,MAX_REPORT_BYTES=10*1024*1024; // the finish route's own limits
|
|
15
15
|
const say=line=>process.stderr.write(line+'\n');
|
|
@@ -29,7 +29,7 @@ export async function connect(host,project){
|
|
|
29
29
|
client.request=async(...args)=>{try{return await request(...args);}catch(error){if(error?.code==='cave_operation_version_conflict')error.message=VERSION_CONFLICT;throw error;}};
|
|
30
30
|
return client;
|
|
31
31
|
}
|
|
32
|
-
export const VERSION_CONFLICT=
|
|
32
|
+
export const VERSION_CONFLICT=versionConflictMessage();
|
|
33
33
|
function projectPath(client){
|
|
34
34
|
if(!/^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/i.test(client.projectId??''))throw new CloudError('cave_project_required','Select a project with --project, CAVE_PROJECT_ID or cvm context bind.',2);
|
|
35
35
|
return `/api/v1/projects/${client.projectId}`;
|
package/bin/cvm.mjs
CHANGED
|
@@ -14,6 +14,9 @@ import {parseArgs} from 'node:util';
|
|
|
14
14
|
import {setTimeout as pause} from 'node:timers/promises';
|
|
15
15
|
import {version,skillDirs,marker,installSkill} from './agents.mjs';
|
|
16
16
|
|
|
17
|
+
// A reader that stops early (cvm tools list | head) closes the pipe: end
|
|
18
|
+
// quietly, as Unix tools do, instead of an unhandled EPIPE stack trace.
|
|
19
|
+
for(const stream of [process.stdout,process.stderr])stream.on('error',error=>{if(error.code!=='EPIPE')throw error;process.exit(process.exitCode??0);});
|
|
17
20
|
const client=()=>import('../dist/cloud-client.mjs');
|
|
18
21
|
const cavemanHome=process.env.CAVEMAN_HOME??join(homedir(),'.caveman');
|
|
19
22
|
const credentialsPath=join(cavemanHome,'credentials');
|
|
@@ -192,6 +195,16 @@ async function setup(args){
|
|
|
192
195
|
return run(args,{client,context,login,call,cvm:realpathSync(fileURLToPath(import.meta.url))});
|
|
193
196
|
}
|
|
194
197
|
|
|
198
|
+
// What cvm answers before the client, for `cvm --help` and `cvm <family>`.
|
|
199
|
+
const commands=[
|
|
200
|
+
{id:'setup',usage:'cvm setup [--project UUID] [--agent claude,codex,...] [--yes] [--no-launch] [--remove]',summary:'Connect your coding agents: sign-in, project, skill and MCP server.'},
|
|
201
|
+
{id:'login',usage:'cvm login [--instance URL] [--no-browser]',summary:'Sign in with the browser.'},
|
|
202
|
+
{id:'logout',usage:'cvm logout',summary:'Sign out and revoke this device.'},
|
|
203
|
+
{id:'mcp',usage:'cvm mcp',summary:'Serve the Cloud MCP server over stdio.'},
|
|
204
|
+
{id:'evals.init',usage:'cvm evals init [PATH]',summary:'Write a starter eval file (example.eval.json).'},
|
|
205
|
+
{id:'evals.ci',usage:'cvm evals ci FILE... | cvm evals ci [--suite NAME] -- TEST_COMMAND',summary:'Gate a pull request on eval files or a CI test run.'},
|
|
206
|
+
{id:'evals.watch',usage:'cvm evals watch RUN_ID',summary:'Follow one run until it settles.'},
|
|
207
|
+
];
|
|
195
208
|
const argv=process.argv.slice(2);
|
|
196
209
|
// What only the operation form of `evals validate` and `evals run` takes.
|
|
197
210
|
// A bare id is the experiment to run, unless it is the value of --project.
|
|
@@ -229,5 +242,5 @@ if(argv[0]==='--version'||argv[0]==='-v'){
|
|
|
229
242
|
process.exitCode=await (argv[1]==='ci'?evalsCI:evalsWatch)(argv.slice(2),{context,login:loginCommand});
|
|
230
243
|
}else{
|
|
231
244
|
const {runCloudCLI}=await client();
|
|
232
|
-
process.exitCode=await runCloudCLI(argv,{context,login:loginCommand});
|
|
245
|
+
process.exitCode=await runCloudCLI(argv,{context,login:loginCommand,commands});
|
|
233
246
|
}
|