archal 0.9.18 → 0.9.20
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 +9 -1
- package/agents/github-octokit/.archal.json +8 -0
- package/agents/github-octokit/Dockerfile +8 -0
- package/agents/github-octokit/README.md +113 -0
- package/agents/github-octokit/agent.mjs +54 -0
- package/agents/github-octokit/package.json +9 -0
- package/agents/github-octokit/scenarios/test-repo-access.md +27 -0
- package/agents/google-workspace-local-tools/Dockerfile +6 -0
- package/agents/google-workspace-local-tools/README.md +58 -0
- package/agents/google-workspace-local-tools/agent.mjs +196 -0
- package/agents/google-workspace-local-tools/archal-harness.json +7 -0
- package/agents/google-workspace-local-tools/run-input.yaml +16 -0
- package/agents/google-workspace-local-tools/scenario.md +29 -0
- package/agents/hermes/.archal.json +8 -0
- package/agents/hermes/Dockerfile +46 -0
- package/agents/hermes/README.md +87 -0
- package/agents/hermes/SOUL.md +27 -0
- package/agents/hermes/config.yaml +34 -0
- package/agents/hermes/drive.mjs +113 -0
- package/agents/hermes/scenarios/stripe-customers-read-only.md +32 -0
- package/agents/openclaw/.archal.json +8 -0
- package/agents/openclaw/Dockerfile +96 -0
- package/agents/openclaw/README.md +120 -0
- package/agents/openclaw/drive.mjs +311 -0
- package/agents/openclaw/package.json +9 -0
- package/agents/openclaw/scenarios/github-issue-triage-read-only.md +44 -0
- package/agents/openclaw/workspace/AGENTS.md +23 -0
- package/agents/openclaw/workspace/IDENTITY.md +8 -0
- package/agents/openclaw/workspace/SOUL.md +14 -0
- package/agents/openclaw/workspace/TOOLS.md +35 -0
- package/agents/pagination-test/README.md +24 -0
- package/agents/pagination-test/scenario.md +24 -0
- package/agents/replay-capsule-harness/README.md +29 -0
- package/agents/replay-capsule-harness/observability-install-offline-e2e.mts +1517 -0
- package/agents/replay-capsule-harness/replay-capsule-e2e.mjs +104 -0
- package/clone-assets/apify/tools.json +213 -13
- package/clone-assets/calcom/tools.json +510 -0
- package/clone-assets/clickup/tools.json +1258 -0
- package/clone-assets/customerio/tools.json +386 -0
- package/clone-assets/datadog/tools.json +734 -0
- package/clone-assets/github/tools.json +312 -25
- package/clone-assets/gitlab/tools.json +999 -0
- package/clone-assets/google-workspace/tools.json +18 -6
- package/clone-assets/hubspot/tools.json +1406 -0
- package/clone-assets/jira/fidelity.json +1 -1
- package/clone-assets/jira/tools.json +266 -543
- package/clone-assets/linear/tools.json +238 -40
- package/clone-assets/ownerrez/tools.json +548 -0
- package/clone-assets/pricelabs/tools.json +343 -0
- package/clone-assets/sentry/tools.json +745 -0
- package/clone-assets/slack/tools.json +1 -2
- package/clone-assets/stripe/tools.json +185 -46
- package/clone-assets/supabase/tools.json +511 -14
- package/clone-assets/unipile/tools.json +408 -0
- package/clone-assets/webflow/tools.json +415 -0
- package/dist/autoloop-worker-types-BEb_E44z.d.cts +196 -0
- package/dist/cli.cjs +151033 -75282
- package/dist/commands/autoloop-hosted-worker.cjs +43942 -0
- package/dist/commands/autoloop-hosted-worker.d.cts +143 -0
- package/dist/commands/autoloop-pr-verification.cjs +4227 -0
- package/dist/commands/autoloop-pr-verification.d.cts +17 -0
- package/dist/{vitest/chunk-IVXSSEYS.js → commands/autoloop-result-parser.cjs} +16515 -18857
- package/dist/commands/autoloop-result-parser.d.cts +39 -0
- package/dist/commands/autoloop-worker.cjs +36163 -0
- package/dist/commands/autoloop-worker.d.cts +97 -0
- package/dist/harness.cjs +1 -0
- package/dist/index.cjs +1 -1
- package/dist/replay.cjs +49624 -0
- package/dist/replay.d.cts +4625 -0
- package/dist/scenarios.cjs +80343 -0
- package/dist/scenarios.d.cts +562 -0
- package/dist/vitest/chunk-6CBYFCFK.js +4667 -0
- package/dist/vitest/chunk-ARVS45PP.js +2764 -0
- package/dist/vitest/index.cjs +6079 -75089
- package/dist/vitest/index.d.ts +7 -6
- package/dist/vitest/index.js +8 -8
- package/dist/vitest/runtime/hosted-session-reaper.cjs +801 -34187
- package/dist/vitest/runtime/hosted-session-reaper.js +1 -1
- package/dist/vitest/runtime/setup-files.js +2 -2
- package/package.json +14 -9
- package/skills/archal-agent/SKILL.md +87 -0
- package/skills/autoloop/SKILL.md +376 -0
- package/skills/autoloop/references/hosted-sources.md +62 -0
- package/skills/autoloop/references/trace-schema-mapping.md +73 -0
- package/skills/eval/SKILL.md +35 -1
- package/skills/install-agent/SKILL.md +221 -0
- package/skills/onboard/SKILL.md +80 -0
- package/skills/scenario/SKILL.md +19 -4
- package/skills/seed/SKILL.md +237 -0
- package/dist/seed/dynamic-generator.cjs +0 -45564
- package/dist/seed/dynamic-generator.d.cts +0 -106
- package/dist/vitest/chunk-CTSN67QR.js +0 -47188
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: seed
|
|
3
|
+
description: Craft and load explicit clone seed state for Archal, deterministically and with no LLM. This is the canonical "how to seed a clone" skill. Use it whenever you need to give a clone (github, stripe, supabase, slack, ...) a known starting state: writing or editing a JSON or SQL seed file, choosing a named catalog seed, wiring a scenario's seed, debugging "seed not found" / "seed_unavailable" / shape-mismatch / rollback errors, or deciding between an inline `## Seed State` block and a committed seed file. Reach for this any time the words seed, seed state, starting state, fixture data, or "set up the clone with..." appear.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
argument-hint: "[clone + the state you want loaded]"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Archal Seed State
|
|
9
|
+
|
|
10
|
+
You craft and load explicit starting state for Archal clones. A seed is the
|
|
11
|
+
clone's state before a run begins: the issues GitHub holds, the customers and
|
|
12
|
+
subscriptions Stripe holds, the rows a Supabase database holds.
|
|
13
|
+
|
|
14
|
+
The one rule that defines this skill: **seeds are explicit, committed, and
|
|
15
|
+
deterministic. No LLM is involved.** You write the state, or you pick a named
|
|
16
|
+
catalog seed someone already wrote. You never ask a model to invent it.
|
|
17
|
+
|
|
18
|
+
The dedicated package that loads seed state, `@archal/seed-state`, says this in
|
|
19
|
+
its own README and it is the mental model to hold:
|
|
20
|
+
|
|
21
|
+
> This package intentionally contains no LLM calls, code generation, natural
|
|
22
|
+
> language extraction, cache, repair, or scenario-to-state generation.
|
|
23
|
+
|
|
24
|
+
## The four shapes a seed can take
|
|
25
|
+
|
|
26
|
+
1. **A committed JSON seed file** — `clones/<clone>/seeds/<name>.json`. A
|
|
27
|
+
top-level object whose keys are the clone's collections and whose values are
|
|
28
|
+
arrays of entities. This is the common shape for object-graph clones
|
|
29
|
+
(github, stripe, slack, linear, jira). Example file:
|
|
30
|
+
`clones/github/seeds/small-project.json`.
|
|
31
|
+
|
|
32
|
+
2. **A committed SQL seed file** — `clones/<clone>/seeds/<name>.sql`. A set of
|
|
33
|
+
`CREATE TABLE` + `INSERT` statements. The natural shape for relational
|
|
34
|
+
clones like `supabase`, whose seeds on disk are `.sql`, not `.json`. Example:
|
|
35
|
+
`clones/supabase/seeds/ecommerce.sql`.
|
|
36
|
+
|
|
37
|
+
3. **A named catalog seed** — a seed that already lives on disk for a clone, so
|
|
38
|
+
you reference it by name instead of writing one. `github: small-project`,
|
|
39
|
+
`stripe: checkout-flow`, `supabase: saas-starter`. Browse them with
|
|
40
|
+
`archal seed list <clone>`.
|
|
41
|
+
|
|
42
|
+
4. **An inline `## Seed State` block in a scenario** — explicit state written
|
|
43
|
+
directly in the scenario markdown. Use it when the state is small and tightly
|
|
44
|
+
coupled to that one scenario. For anything reused across scenarios, prefer a
|
|
45
|
+
committed file (shapes 1–3) so it has one home.
|
|
46
|
+
|
|
47
|
+
Resolution on disk checks `<name>.json` first, then `<name>.sql`
|
|
48
|
+
(`loadSeedStateFromPath` in `packages/seed-state/src/state.ts`). A clone can
|
|
49
|
+
ship either form for a given seed name, not both.
|
|
50
|
+
|
|
51
|
+
## How a scenario or the CLI selects a seed
|
|
52
|
+
|
|
53
|
+
A seed value comes from one of two places, parsed identically:
|
|
54
|
+
|
|
55
|
+
- The scenario `## Config` key `seed:`
|
|
56
|
+
- The CLI flag `archal run --seed <name-or-path>`
|
|
57
|
+
|
|
58
|
+
Both accept the same forms (verbatim from the `--seed` flag help):
|
|
59
|
+
|
|
60
|
+
> Seed name (e.g. small-project), clone-prefixed name (github:small-project,
|
|
61
|
+
> applies only to that clone), seed family (enterprise, stale, ...), or local
|
|
62
|
+
> file path (.json / .md).
|
|
63
|
+
|
|
64
|
+
So the two everyday shapes are:
|
|
65
|
+
|
|
66
|
+
- **Bare name** — `seed: small-project`. Applies to every clone the scenario
|
|
67
|
+
declares.
|
|
68
|
+
- **Clone-prefixed** — `seed: github:small-project`. Applies only to the named
|
|
69
|
+
clone. This matches `archal clone start --seed github:small-project`, so the
|
|
70
|
+
same string works in both commands.
|
|
71
|
+
|
|
72
|
+
The prefix is validated: if you write `seed: payments:checkout-flow` but the
|
|
73
|
+
scenario never declares a `payments` clone, you get a usage error naming the
|
|
74
|
+
clones the scenario actually has, rather than a confusing `seed_unavailable`
|
|
75
|
+
later from the runtime (`parseExplicitSeed` in
|
|
76
|
+
`cli/src/runner/seed-resolution.ts`).
|
|
77
|
+
|
|
78
|
+
One behavior to remember: a scenario with a `## Setup` section but **no**
|
|
79
|
+
explicit `seed:` is forced to the `empty` seed, because Setup prose used to
|
|
80
|
+
drive dynamic generation and a pre-populated seed would conflict with it. To
|
|
81
|
+
combine a Setup description with a real seed, you must add an explicit `seed:`
|
|
82
|
+
field. (See `resolveRunSeedPlan` in `cli/src/runner/seed-resolution.ts`.)
|
|
83
|
+
|
|
84
|
+
### Command surface
|
|
85
|
+
|
|
86
|
+
| Command | What it does |
|
|
87
|
+
|---------|--------------|
|
|
88
|
+
| `archal seed list` | One row per clone: clone, default seed, seed count |
|
|
89
|
+
| `archal seed list <clone>` | Every seed for that clone, with the default marked |
|
|
90
|
+
| `archal seed list <clone> --json` | Same, machine-readable |
|
|
91
|
+
| `archal run <scenario>.md --seed <name-or-path>` | Override the seed for a run |
|
|
92
|
+
| `archal run ... --fresh-seed` | On a reused clone session, reset and re-apply the seed |
|
|
93
|
+
| `archal run ... --keep-state` | On a reused session, keep existing state, do not re-apply |
|
|
94
|
+
| `archal clone start <clone> --seed <seeds...>` | Start a live clone pre-seeded |
|
|
95
|
+
| `archal clone start <clone> --seed-file <path>` | Start a live clone, then load a JSON/markdown seed file |
|
|
96
|
+
| `archal clone seed --file <path>` | Sideload a JSON seed file into a running clone |
|
|
97
|
+
|
|
98
|
+
Prefer `archal seed list` over memorizing a seed table. The catalog is derived
|
|
99
|
+
from `clones/<clone>/seeds/*.{json,sql}` on disk, so the CLI is always current.
|
|
100
|
+
|
|
101
|
+
## The deterministic load flow
|
|
102
|
+
|
|
103
|
+
When a run seeds a clone, the loader does this, in order
|
|
104
|
+
(`packages/runtime/src/seed-loader.ts`):
|
|
105
|
+
|
|
106
|
+
1. **Snapshot first.** `GET /state` on each target clone and keep the response
|
|
107
|
+
text. This is the rollback point (`snapshotSeedTargets` →
|
|
108
|
+
`fetchSeedStateSnapshot`).
|
|
109
|
+
2. **Apply the seed.** `PUT /state` with the seed body — `application/json` for
|
|
110
|
+
a JSON seed, `text/sql` for a SQL seed — one clone at a time, tracking each
|
|
111
|
+
one that committed.
|
|
112
|
+
3. **Roll back on failure.** If any clone's load throws, restore the clones that
|
|
113
|
+
already committed by replaying their snapshots, then re-throw the original
|
|
114
|
+
error (`restoreSeedTargets`). A clone is never left half-seeded.
|
|
115
|
+
4. **Capture the baseline after seeding.** Once seeding succeeds, the post-seed
|
|
116
|
+
state is captured as the baseline (`captureBaselineStates` in
|
|
117
|
+
`packages/runtime/src/clone-client.ts`). Resets between runs restore *this*
|
|
118
|
+
seeded baseline, not an empty clone — so every run in a multi-run scenario
|
|
119
|
+
starts from the same seeded state.
|
|
120
|
+
|
|
121
|
+
### How state reaches the clone (the `/state` endpoint)
|
|
122
|
+
|
|
123
|
+
The clone server exposes `/state` (`clones/core/src/rest/rest-built-in-endpoints.ts`):
|
|
124
|
+
|
|
125
|
+
- `GET /state` — read the current state (used for the snapshot and baseline).
|
|
126
|
+
- `PUT /state` — load state. The handler branches on `Content-Type`:
|
|
127
|
+
- `text/sql` or `application/sql` → parsed and loaded as SQL (only when the
|
|
128
|
+
clone exposes SQL loading; otherwise it returns a 400 telling you to send
|
|
129
|
+
JSON).
|
|
130
|
+
- otherwise → loaded as JSON state.
|
|
131
|
+
- `PUT /state?seed=<name>` with a `{}` body → load a named catalog seed
|
|
132
|
+
server-side, without sending a state body at all.
|
|
133
|
+
- `DELETE /state` — wipe state (used by `--fresh-seed` before re-applying).
|
|
134
|
+
|
|
135
|
+
A successful `PUT` returns `{ ok: true }`. The content-type the CLI sends is set
|
|
136
|
+
in one place — `text/sql` when there is SQL, `application/json` otherwise
|
|
137
|
+
(`pushStateToCloud` in `cli/src/runner/execution/agent-http.ts`); named-seed
|
|
138
|
+
loads always send `application/json` with an empty body.
|
|
139
|
+
|
|
140
|
+
## Do not do these
|
|
141
|
+
|
|
142
|
+
- **Do not synthesize seed data from scenario prose.** A `## Setup` paragraph is
|
|
143
|
+
context for the evaluator, not a source you extract state from. If you need
|
|
144
|
+
populated state, write a committed seed (or pick a named one) and reference it
|
|
145
|
+
with `seed:`.
|
|
146
|
+
- **Do not call an LLM to generate, repair, or "fill in" a seed.** The old
|
|
147
|
+
dynamic seed-generation path is being removed; `@archal/seed-state` was built
|
|
148
|
+
specifically to have none of it. Explicit committed seeds only.
|
|
149
|
+
- **Do not invent collection names.** A JSON seed must use the clone's real
|
|
150
|
+
collection keys (see "Writing a good JSON seed"). Unknown keys are dropped by
|
|
151
|
+
normalization, so a typo silently seeds nothing.
|
|
152
|
+
- **Do not hand-tune both `.json` and `.sql` for the same name.** Pick one form
|
|
153
|
+
per seed name; resolution stops at the first that exists.
|
|
154
|
+
- **Do not blow away a sideloaded session by accident.** On a reused
|
|
155
|
+
`archal clone start` session the loader probes for existing state before
|
|
156
|
+
re-applying. Use `--keep-state` to keep it or `--fresh-seed` to reset on
|
|
157
|
+
purpose, rather than fighting the guard.
|
|
158
|
+
|
|
159
|
+
## Writing a good JSON seed
|
|
160
|
+
|
|
161
|
+
The seed file must mirror the clone's real state shape. The fastest reliable way
|
|
162
|
+
to get the shape right is to open an existing catalog seed for that clone and
|
|
163
|
+
match its top-level keys and per-entity fields.
|
|
164
|
+
|
|
165
|
+
A JSON seed is a top-level object: each key is a collection, each value is an
|
|
166
|
+
array of entity objects.
|
|
167
|
+
|
|
168
|
+
```jsonc
|
|
169
|
+
{
|
|
170
|
+
"users": [{ "id": "u1", "login": "octocat", "type": "User" }],
|
|
171
|
+
"repos": [{ "id": "r1", "name": "demo", "fullName": "octocat/demo", "private": false }],
|
|
172
|
+
"issues": [{ "id": "i1", "repoId": "r1", "number": 1, "title": "First issue", "state": "open" }]
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Match the clone, not your imagination:
|
|
177
|
+
|
|
178
|
+
- Use the same collection names the clone uses. `clones/github/seeds/small-project.json`
|
|
179
|
+
has `users`, `repos`, `issues`, `pullRequests`, `labels`, and more.
|
|
180
|
+
- Give each entity the fields the clone expects, especially `id` and the foreign
|
|
181
|
+
keys that wire entities together (`repoId`, `issueNumber`, ...). The clone
|
|
182
|
+
maintains those relationships; broken references produce realistic errors at
|
|
183
|
+
runtime, not seed-time.
|
|
184
|
+
- Only arrays survive normalization — non-array top-level values are dropped
|
|
185
|
+
(`normalizeSeedState`). Keep everything in collection arrays.
|
|
186
|
+
|
|
187
|
+
## When SQL fits
|
|
188
|
+
|
|
189
|
+
Use a `.sql` seed for relational clones whose state is naturally tables and
|
|
190
|
+
rows — `supabase` is the canonical case, and its seeds on disk are `.sql`. The
|
|
191
|
+
SQL seed is plain `CREATE TABLE` + `INSERT INTO ... VALUES (...)`:
|
|
192
|
+
|
|
193
|
+
```sql
|
|
194
|
+
CREATE TABLE customers (id serial, email text, name text);
|
|
195
|
+
INSERT INTO customers (email, name) VALUES
|
|
196
|
+
('ada@example.com', 'Ada Lovelace'),
|
|
197
|
+
('alan@example.com', 'Alan Turing');
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
The SQL parser is deliberately small (`parseSqlSeed` in
|
|
201
|
+
`packages/seed-state/src/state.ts`): it understands `CREATE TABLE` (including
|
|
202
|
+
`IF NOT EXISTS`), `INSERT INTO ... VALUES`, schema-qualified and quoted
|
|
203
|
+
identifiers, line and block comments, and auto-assigns serial `id`s. It is not a
|
|
204
|
+
full SQL engine — anything other than `CREATE TABLE` / `INSERT` throws an
|
|
205
|
+
"Unsupported SQL seed statement" error. Keep seeds to those two statements.
|
|
206
|
+
|
|
207
|
+
## Failure taxonomy
|
|
208
|
+
|
|
209
|
+
| Symptom | Likely cause | Fix |
|
|
210
|
+
|---------|--------------|-----|
|
|
211
|
+
| `Could not resolve static seed "<name>"` / `seed_unavailable` | Seed name is misspelled, not in this clone's catalog, or the hosted session was started with a different seed | `archal seed list <clone>` to confirm the name; re-provision the session with the right seed |
|
|
212
|
+
| `clone "<x>" is not part of this scenario` | Clone-prefixed seed names a clone the scenario doesn't declare | Add the clone to `clones:`, or drop the prefix |
|
|
213
|
+
| Seed loads but state looks empty / partial | Wrong collection keys, or non-array top-level values dropped by normalization | Match an existing catalog seed's keys; keep every collection an array |
|
|
214
|
+
| `Failed to parse seed file ...` | Malformed JSON | Validate the JSON; check trailing commas and quoting |
|
|
215
|
+
| `Unsupported SQL seed statement: ...` | SQL beyond `CREATE TABLE` / `INSERT` | Reduce the seed to those two statements |
|
|
216
|
+
| `…does not expose SQL state loading` (HTTP 400) | Sent SQL to a clone that only loads JSON | Send JSON state, or use a clone that supports SQL |
|
|
217
|
+
| `Rollback failed after partial seed load` | A clone errored mid-load and the snapshot restore also failed | The clones may be in a mixed state; restart the clone session and retry |
|
|
218
|
+
| Seed "not re-applied" warning on a reused session | The loader kept existing sideloaded state instead of overwriting it | `--fresh-seed` to reset and re-apply, or `--keep-state` to accept it on purpose |
|
|
219
|
+
|
|
220
|
+
## What to report back
|
|
221
|
+
|
|
222
|
+
After authoring or loading a seed, tell the user:
|
|
223
|
+
|
|
224
|
+
- the clone(s) and the seed shape used (named catalog seed, JSON file, SQL file,
|
|
225
|
+
or inline `## Seed State`)
|
|
226
|
+
- the seed name or file path, and how a scenario/run selects it (`seed:` or
|
|
227
|
+
`--seed`)
|
|
228
|
+
- the entity counts loaded per clone (the loader logs e.g. `7 issues, 3 repos`)
|
|
229
|
+
- for a new seed file, that it mirrors an existing catalog seed's shape
|
|
230
|
+
- any blocker: missing seed name, shape mismatch, SQL parse error, or a rollback
|
|
231
|
+
that fired — with the exact next command
|
|
232
|
+
|
|
233
|
+
## Docs
|
|
234
|
+
|
|
235
|
+
- Seeds guide: https://docs.archal.ai/guides/seeds
|
|
236
|
+
- Clones and seeds overview: https://docs.archal.ai/clones/overview
|
|
237
|
+
- Writing scenarios: https://docs.archal.ai/guides/writing-scenarios
|