@mechasm/cli 0.1.3 → 0.1.5

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/AGENT_GUIDE.md CHANGED
@@ -2,8 +2,20 @@
2
2
 
3
3
  Use Node.js 22 or newer. Install `@mechasm/cli`, sign in with `mechasm login`, then check `mechasm doctor`.
4
4
 
5
+ When signing in again with a valid session and the same account, review the preselected project and team approvals before approving.
6
+
5
7
  Keep each test request in Markdown. Name the project ID, target URL, expected result, and limits. Reuse configured test accounts; do not ask agents to expose credentials or change data outside the named test scope.
6
8
 
9
+ Before creating a test, list the project's existing tests and inspect likely matches. If the target and requirements match, run the existing test and inspect the new run. An app change alone does not require a new test. Edit a test when its requirements change; create one only for missing coverage. Never reuse an old result as verification of a new app version.
10
+
11
+ ```sh
12
+ mechasm tests list --project PROJECT_ID --json
13
+ mechasm tests get TEST_ID --project PROJECT_ID --json
14
+ mechasm tests run TEST_ID --project PROJECT_ID --json
15
+ ```
16
+
17
+ For missing coverage:
18
+
7
19
  ```sh
8
20
  mechasm tests create --project PROJECT_ID --name "Sign-in" --prompt-file prompt.md --json
9
21
  ```
@@ -22,8 +34,21 @@ mechasm runs status RUN_ID --project PROJECT_ID --json
22
34
 
23
35
  Log streaming alone does not report pass/fail through its exit code. Do not infer success from a closed stream or an individual log line. For scripts that only need the final result, `--wait` on create/edit/run or `runs wait` waits silently and returns the final result without displaying live logs. With `--json`, it returns one final JSON result.
24
36
 
37
+ Let Mechasm's healer work while the run is active. Failed actions, unexpected pages and recovery attempts can be corrected automatically. Wait for the overall run to reach `passed` or `failed`; do not cancel because a few minutes passed or one step failed. Stop when the user requests it, or when you deliberately need to change the prompt before continuing. `runs status` includes `terminal`, the current `progress` phase/start time when available, and safe failure details with a suggested next step. Missing progress is not proof the run is stuck.
38
+
39
+ Before reporting the outcome, review the logs and available evidence against the user's intended result:
40
+
41
+ ```sh
42
+ mechasm runs trace RUN_ID --project PROJECT_ID --out run-trace.zip
43
+ mechasm runs video RUN_ID --project PROJECT_ID --out run.webm
44
+ ```
45
+
46
+ Check artifact availability in `runs status`; uploads can finish after the run result. Inspect trace screenshots/page snapshots, actions and errors, using video as supporting evidence. Verify that the expected behavior really happened; do not treat an existing file as proof of success. If evidence is unavailable or cannot be opened, report that limit.
47
+
48
+ If evidence shows a genuine failure of the user's requirement, accept and report the failure. If your prompt introduced an unsupported assumption or was ambiguous, clarify it without weakening the user's requirement, then use `tests edit --prompt-file FILE` and inspect the new run. Ask the user if their intended result is unclear. Do not repeatedly rerun or remove assertions just to get a pass. A manually stopped run proves cancellation, not what the natural result would have been.
49
+
25
50
  Use explicit project, test, and run IDs. Do not assume a default project. Use `--json` for scripts; stdout contains JSON and errors go to stderr. Log following emits JSON lines. Save run IDs and log cursors in workflow state. Resume logs with `--after CURSOR` after reconnecting.
26
51
 
27
52
  Exit code `5` from a status/get/wait command or a test command using `--wait` means the run failed or was stopped. Code `2` means invalid arguments, `3` authentication failed, and `4` permission was denied. The optional npm update notice runs only in interactive non-JSON sessions; CI skips it.
28
53
 
29
- See [CLI documentation](https://mechasm.ai/docs/mechasm-cli/getting-started) for full command details.
54
+ See [CLI documentation](https://mechasm.ai/docs/mechasm-cli/getting-started) and [agent workflows](https://mechasm.ai/docs/mechasm-cli/agent-workflows) for full command details.
package/README.md CHANGED
@@ -31,6 +31,8 @@ mechasm projects list
31
31
 
32
32
  Approve the existing projects and actions this device needs. Project access and permission to create projects in a team are separate. Team project-creation access does not grant access to existing projects in that team. If a project or team is missing, sign in again and approve access; your account must already have access to it.
33
33
 
34
+ When signing in again with a valid session and the same account, your previous approvals are preselected. Review them before approving. If your session has expired or was revoked, select access again.
35
+
34
36
  Pass project IDs explicitly to test, run, variable, and local-app commands. The CLI does not select a default project.
35
37
 
36
38
  ## Create a project and run a test
@@ -43,6 +45,8 @@ mechasm tests create --project PROJECT_ID --name "Home page" --prompt "Open the
43
45
 
44
46
  Replace `TEAM_ID`, `PROJECT_ID`, and the example URL with your values. `--team` is optional when exactly one team is approved. The project creation response contains the project ID to use in later commands.
45
47
 
48
+ For later app changes, inspect existing tests and run matching ones with `mechasm tests run TEST_ID --project PROJECT_ID`. Edit tests when requirements change; create tests only for missing coverage. Always inspect the new run's result. See the bundled [Agent Guide](./AGENT_GUIDE.md) for the full workflow.
49
+
46
50
  Commands that start a run return its `runId` and workspace `runUrl`. Use the returned run ID to follow execution:
47
51
 
48
52
  ```sh
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mechasm/cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Mechasm command line client",
5
5
  "homepage": "https://mechasm.ai/docs/mechasm-cli/getting-started",
6
6
  "license": "SEE LICENSE IN LICENSE",
package/src/api-client.js CHANGED
@@ -228,7 +228,19 @@ export function createCliClient(rawApiUrl) {
228
228
  async login({ deviceName = hostname().slice(0, 120), noBrowser = false, json = false } = {}) {
229
229
  deviceName = String(deviceName).trim();
230
230
  if (!deviceName || deviceName.length > 120) throw new CliError('--device-name must be 1 to 120 characters.', 2);
231
- const device = (await request('/auth/device', { method: 'POST', body: { deviceName } })).data;
231
+ let previousToken;
232
+ try {
233
+ if (await readCredentials(path)) previousToken = (await accessToken()).token;
234
+ } catch (error) {
235
+ if (error.exitCode !== 3) throw error;
236
+ }
237
+ let device;
238
+ try {
239
+ device = (await request('/auth/device', { method: 'POST', body: { deviceName }, token: previousToken })).data;
240
+ } catch (error) {
241
+ if (!previousToken || error.exitCode !== 3) throw error;
242
+ device = (await request('/auth/device', { method: 'POST', body: { deviceName } })).data;
243
+ }
232
244
  if (typeof device?.deviceCode !== 'string' || !/^mcd_[A-Za-z0-9_-]{43}$/.test(device.deviceCode) ||
233
245
  typeof device?.userCode !== 'string' || !device.userCode || typeof device?.verificationUrl !== 'string' ||
234
246
  !Number.isInteger(device.expiresIn) || device.expiresIn < 1 || device.expiresIn > 1800) {
package/src/cli.js CHANGED
@@ -181,7 +181,10 @@ function output(value, json) {
181
181
  console.log(`Signed in${identity ? ` as ${identity}` : ''}${value.deviceName ? ` (${value.deviceName})` : ''}.`);
182
182
  }
183
183
  else if (Array.isArray(value?.projects)) {
184
- if (!value.projects.length) console.log('No projects available.');
184
+ if (!value.projects.length) {
185
+ console.log(value.message || 'No projects available to this device.');
186
+ if (value.suggestedNextStep) console.log(value.suggestedNextStep);
187
+ }
185
188
  else for (const project of value.projects) console.log(`${project.id} ${project.name} ${project.url}`);
186
189
  } else if (Array.isArray(value?.tests)) {
187
190
  if (!value.tests.length) console.log('No tests found.');