@sente-labs/cli 0.8.0 → 0.8.1
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/index.js +1 -1
- package/dist/skill/SKILL.md +15 -1
- package/dist/skill/autoupdate.js +9 -1
- package/dist/skill/autoupdate.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25,7 +25,7 @@ const program = new commander_1.Command();
|
|
|
25
25
|
program
|
|
26
26
|
.name('sente')
|
|
27
27
|
.description('Sente CLI -- manage QA tests from the command line and Claude Code')
|
|
28
|
-
.version('0.8.
|
|
28
|
+
.version('0.8.1')
|
|
29
29
|
.option('--json', 'Emit machine-readable JSON instead of human output');
|
|
30
30
|
/**
|
|
31
31
|
* Global options aren't auto-propagated to subcommands by Commander, so we
|
package/dist/skill/SKILL.md
CHANGED
|
@@ -27,6 +27,13 @@ Sente runs QA tests against the user's deployed staging environment via a cloud-
|
|
|
27
27
|
|
|
28
28
|
## Workflow recipes
|
|
29
29
|
|
|
30
|
+
### 0. Onboarding — repo not bound to Sente yet
|
|
31
|
+
|
|
32
|
+
If there's no `.sente/config.json`, this repo isn't bound to a project. Don't guess at commands — bind it with `sente init`:
|
|
33
|
+
|
|
34
|
+
- `sente init --name <repo> --staging-url https://<public-staging-url> --non-interactive` — creates the project + a default "Smoke tests" workflow, writes `.sente/config.json` + `.sente/tasks.json`, and installs/refreshes this skill. It needs a **public staging URL** (ask the user if you don't know it; `localhost`/PR previews won't work) and runs `sente login` automatically if you're not authenticated.
|
|
35
|
+
- If `.sente/` **already** exists, do NOT re-init — use `sente sync` to refresh `.sente/tasks.json`, or `sente project set --url <url>` to fix the staging URL.
|
|
36
|
+
|
|
30
37
|
### A. Creating a new test
|
|
31
38
|
|
|
32
39
|
1. Read `.sente/config.json` and `.sente/tasks.json` to confirm the project exists and to learn the staging baseUrl.
|
|
@@ -55,6 +62,9 @@ When the user pastes a failure or asks why a run failed:
|
|
|
55
62
|
2. Read `failureCategory` and `suggestedFix`:
|
|
56
63
|
- **`regression`**: the app is broken. Stop, summarize what failed in plain English, and ask whether to file a bug. Do NOT auto-edit the test.
|
|
57
64
|
- **`test_design`**: the test is wrong for the current app. Propose a fix to the steps, then update the task using recipe B.
|
|
65
|
+
- **Inconclusive** (`agent_loop_exhausted`, `stagnation_auto_fail`, `secret_not_resolved` — shown as a neutral **INCONCLUSIVE** badge, not red): the run could not complete or verify the step. This is **not** a verdict on the app or the test — do NOT call it a pass, and do NOT loosen the assertion to force one.
|
|
66
|
+
- `secret_not_resolved`: a `{{secret.*}}` placeholder had no value. Verify with `sente secret list --json` and create/link it (see Hard rules) — don't edit the step text.
|
|
67
|
+
- `agent_loop_exhausted` / `stagnation_auto_fail`: the agent ran out of room or got stuck on a step (commonly an element it couldn't find, a missing wait, or an earlier step that stalled). Confirm the deploy landed and — for authenticated flows — the seeded session is still valid, then re-run once. Only reclassify as `test_design` (the UI changed) or `regression` (a control is genuinely broken/missing) if it reproduces on the same step.
|
|
58
68
|
3. If the failure is ambiguous, fetch full details with `sente task show <id> --json` and inspect step-by-step `actual` vs `assertion`.
|
|
59
69
|
|
|
60
70
|
### D. Authenticated flows (SSO / 2FA)
|
|
@@ -74,7 +84,7 @@ If a flow needs login, first determine the auth type (check the app or its repo)
|
|
|
74
84
|
|
|
75
85
|
### E. Running tests (one task, a workflow, or a whole project)
|
|
76
86
|
|
|
77
|
-
|
|
87
|
+
Run only after the deploy you want to test has landed (see Critical context).
|
|
78
88
|
|
|
79
89
|
- **One task**: `sente task run <taskId>`.
|
|
80
90
|
- **A whole workflow** (all its tasks, in order): `sente workflow run <workflowId>`. Get ids with `sente workflow list --json`.
|
|
@@ -144,11 +154,13 @@ The agent that runs your tests enforces this style. Steps that follow it pass mo
|
|
|
144
154
|
- Bad: `Verify text "Welcome back, John!" appears` (exact wording rigid)
|
|
145
155
|
- Bad: `The save succeeds` (no observable)
|
|
146
156
|
- Counts and existence are LITERAL: `"no results"` means zero, not "22 unrelated".
|
|
157
|
+
- For a **long-running / async outcome** (export or file generation, email/notification delivery, a queued or background job), assert the **kickoff** — the immediate observable state change (e.g. a button flips to "Processing…", a badge shows "Queued") — not the eventual completion. The runtime waits only briefly after an action, so asserting the final result will time out or flake. This redirects the assertion to a reliably-observable signal; it does not mean asserting less.
|
|
147
158
|
|
|
148
159
|
### Hard rules
|
|
149
160
|
|
|
150
161
|
- **Secrets** use literal placeholder syntax: `{{secret.name_here}}`. Never embed values. List existing secrets with `sente secret list --json`. If the secret doesn't exist, create it with `sente secret create --name <key>` (prompts for value with no echo) or pipe via `echo "$VAL" | sente secret create --name <key> --value-stdin`. Link to the current project with `--project $(jq -r .projectId .sente/config.json)`.
|
|
151
162
|
- **Never invent dropdown values**, product names, or emails. If you don't know, ask the user.
|
|
163
|
+
- **State and satisfy preconditions.** If the flow only works when the account already has certain data (a linked account/entity, an existing record, a non-empty list, an enabled plan/feature), either add early steps that create it, or assert the precondition up front so a missing one fails clearly instead of derailing a later step. For authenticated flows, the seeded profile must already satisfy these (see Recipe D).
|
|
152
164
|
- **Combine related micro-actions into one step** (form fill + submit = one step).
|
|
153
165
|
- **At most 20 steps per task.** If a flow needs more, split into multiple tasks with a precondition note in the second one's instruction.
|
|
154
166
|
- **Cleanup**: if the test creates data, the last step deletes it.
|
|
@@ -163,6 +175,8 @@ The top-level `--instruction` is consulted by the agent when step text is ambigu
|
|
|
163
175
|
| Command | Purpose |
|
|
164
176
|
|---|---|
|
|
165
177
|
| `sente whoami --json` | Confirm auth and current org |
|
|
178
|
+
| `sente login [--token <pat>]` | Store/validate a Personal Access Token (from the Sente dashboard). `sente init` runs this automatically when not authenticated |
|
|
179
|
+
| `sente init --name <name> --staging-url <url> [--workflow <name>] [--non-interactive]` | Bind this repo to a new Sente project + scaffold `.sente/`. See Recipe 0 |
|
|
166
180
|
| `sente project list --json` | List all projects in the org (id, name, baseUrl, default) |
|
|
167
181
|
| `sente project show --json` | Show the project bound to this repo |
|
|
168
182
|
| `sente project set [--id <id>] --url <baseUrl> \| --name <name> --json` | Update the project server-side (staging URL / name) and sync `.sente/config.json`. Use this to change the staging URL — never hand-edit the config file |
|
package/dist/skill/autoupdate.js
CHANGED
|
@@ -46,7 +46,8 @@ const config_1 = require("../config");
|
|
|
46
46
|
*
|
|
47
47
|
* - No marker → user-customized skill; leave it alone.
|
|
48
48
|
* - Marker matches CLI version → up to date; no-op.
|
|
49
|
-
* -
|
|
49
|
+
* - Installed marker NEWER than this CLI → don't downgrade; leave it alone.
|
|
50
|
+
* - Installed marker OLDER than this CLI → auto-upgrade. Print a stderr notice.
|
|
50
51
|
*
|
|
51
52
|
* All errors are swallowed: this is a UX nicety, not a correctness gate.
|
|
52
53
|
* Skipped when `--json` is in argv so machine consumers see clean output.
|
|
@@ -64,6 +65,13 @@ function autoUpdateSkillIfStale() {
|
|
|
64
65
|
return; // user-customized; respect it
|
|
65
66
|
if (installedVersion === template_1.CLI_VERSION)
|
|
66
67
|
return; // already current
|
|
68
|
+
// Downgrade floor: never clobber a NEWER installed skill with this (older)
|
|
69
|
+
// CLI's bundled copy. Without this, a stale global CLI (e.g. not yet
|
|
70
|
+
// `npm i -g`'d to latest) thrashes a newer skill back down on every
|
|
71
|
+
// invocation — silently stripping commands/guidance the newer skill added.
|
|
72
|
+
// Upgrades (installed older than CLI) still proceed below.
|
|
73
|
+
if (isNewer(installedVersion, template_1.CLI_VERSION))
|
|
74
|
+
return;
|
|
67
75
|
fs.writeFileSync(dest, template_1.SKILL_MD);
|
|
68
76
|
process.stderr.write(`sente: refreshed Claude Code skill (${installedVersion} -> ${template_1.CLI_VERSION}). Restart Claude Code to pick up changes.\n`);
|
|
69
77
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoupdate.js","sourceRoot":"","sources":["../../src/skill/autoupdate.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"autoupdate.js","sourceRoot":"","sources":["../../src/skill/autoupdate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED