foldrun 0.6.0 → 0.8.0
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 +98 -16
- package/bin/foldrun.mjs +333 -46
- package/docs/agents.md +483 -0
- package/docs/api-usage.md +156 -0
- package/docs/api.md +435 -0
- package/docs/backups-and-restore.md +171 -0
- package/docs/budgets-and-billing.md +362 -0
- package/docs/cli.md +449 -0
- package/docs/coding-agents.md +224 -0
- package/docs/deploying.md +77 -0
- package/docs/evals.md +90 -0
- package/docs/faq.md +53 -0
- package/docs/flows.md +670 -0
- package/docs/getting-started.md +142 -0
- package/docs/glossary.md +78 -0
- package/docs/harness.md +128 -0
- package/docs/how-it-works.md +255 -0
- package/docs/introduction.md +47 -0
- package/docs/knowledge-and-memory.md +85 -0
- package/docs/notifications.md +320 -0
- package/docs/providers.md +241 -0
- package/docs/runs.md +238 -0
- package/docs/scheduling.md +103 -0
- package/docs/secrets.md +163 -0
- package/docs/security.md +167 -0
- package/docs/self-hosting.md +65 -0
- package/docs/status.md +73 -0
- package/docs/storage-and-sharing.md +118 -0
- package/docs/team-and-access.md +146 -0
- package/docs/tools.md +1810 -0
- package/docs/troubleshooting.md +155 -0
- package/docs/versions.md +79 -0
- package/docs/workspaces.md +160 -0
- package/package.json +9 -5
- package/src/commands.mjs +6487 -260
- package/src/guide.mjs +172 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Troubleshooting
|
|
2
|
+
|
|
3
|
+
The failures people actually hit, what the platform is telling you, and the
|
|
4
|
+
fix. Every one of these leaves its reason in the run's events; read those
|
|
5
|
+
before anything else.
|
|
6
|
+
|
|
7
|
+
## When a provider says no
|
|
8
|
+
|
|
9
|
+
The status code decides what happens next, and the runtime already acts on
|
|
10
|
+
the difference:
|
|
11
|
+
|
|
12
|
+
| code | what it means | what the runtime does |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| **400** | the request is malformed | fails the step — retrying sends the same thing |
|
|
15
|
+
| **401 / 403** | not signed in, or not allowed | tries the fallback provider if one is declared |
|
|
16
|
+
| **402** | out of credit | fallback provider; often a reservation against a large token ceiling rather than an empty account |
|
|
17
|
+
| **404** | no such model or path | fails; usually a base_url with the wrong `format:` |
|
|
18
|
+
| **422** | understood and refused | fails, with the reason in the step's output |
|
|
19
|
+
| **429** | too many requests | **waits and asks again** — up to three times, 2s / 4s / 8s with jitter, honouring a `retry-after` the provider names, on the same key. A 429 that mentions quota, credit or billing is the account, not the traffic, and goes to the fallback instead |
|
|
20
|
+
| **500 / 502 / 503 / 529** | broken or busy at their end | same wait-and-retry as 429 |
|
|
21
|
+
|
|
22
|
+
Every wait is a line in the run log (`provider busy … waiting 3.4s, attempt
|
|
23
|
+
1 of 3`), so a slow run reads as slow rather than mysterious. Only after the
|
|
24
|
+
retries are spent is the fallback provider tried.
|
|
25
|
+
|
|
26
|
+
## "verify … → no match"
|
|
27
|
+
|
|
28
|
+
The step's `verify: matches:` or `contains:` did not find its text in what
|
|
29
|
+
the agent concluded. The check reads the step's **final reply**, and its
|
|
30
|
+
first line is the run's headline — so a reporter that opened with "Done."
|
|
31
|
+
and put the verdict on line three fails a `^BAD` check with the right
|
|
32
|
+
verdict sitting there. Tell the agent the first line *is* the verdict, and
|
|
33
|
+
move a step that cannot manage it to a stronger tier.
|
|
34
|
+
|
|
35
|
+
## "each: the previous group produced no items"
|
|
36
|
+
|
|
37
|
+
`each: lines` splits what the previous step concluded into lines and found
|
|
38
|
+
none. Usually the step wrote its list to a file and replied with a sentence.
|
|
39
|
+
Either have it reply with the list, or use `each: rows of <file>` — a file
|
|
40
|
+
has no turns and is the better contract for a list that must arrive exactly.
|
|
41
|
+
|
|
42
|
+
## "over budget — $x spent of the flow's $y"
|
|
43
|
+
|
|
44
|
+
The run crossed its `budget:` between two groups; the remaining steps were
|
|
45
|
+
skipped. Look at which step spent it: a fast-tier agent writing a file one
|
|
46
|
+
line per call, re-sending its whole context each time, is the usual culprit.
|
|
47
|
+
Put `model:` on that step, tell the agent to write each file once, and set
|
|
48
|
+
the cap at two or three times a normal run so real work never trips it.
|
|
49
|
+
|
|
50
|
+
## "over budget — nothing left to spend before this step (budget: on the … agent)"
|
|
51
|
+
|
|
52
|
+
The agent's own `budget:` — the most it may spend in one run — was used up
|
|
53
|
+
by its earlier steps in this run, so this one was refused before it started.
|
|
54
|
+
Raise the number in that agent's `agent.md`, or take it out: unset is no
|
|
55
|
+
limit. The same line with `budget: in the flow file` is the flow's cap and
|
|
56
|
+
lives there instead.
|
|
57
|
+
|
|
58
|
+
## "is at its budget — $x spent today of $y/day"
|
|
59
|
+
|
|
60
|
+
A cap over time, reached. New runs refuse until the window turns — tomorrow,
|
|
61
|
+
next week, the new month — in the account's own `timezone:`. Raise it in
|
|
62
|
+
Settings or in the file, or remove the line.
|
|
63
|
+
|
|
64
|
+
## "was denied: … is outside this workspace"
|
|
65
|
+
|
|
66
|
+
The agent reached for a path outside its workspace — `/tmp/something`, an
|
|
67
|
+
absolute path, a checkout a tool made — and was refused. The message names
|
|
68
|
+
the path it probably meant. It costs a turn, nothing more; if one step
|
|
69
|
+
collects many, name the exact path in its prompt (`workspace/storage/x.md`).
|
|
70
|
+
|
|
71
|
+
## "this push is not live yet — runs in flight"
|
|
72
|
+
|
|
73
|
+
The push was accepted and will apply when the runs finish. A run parked at
|
|
74
|
+
an approval gate counts. Decide the gate, or wait; `foldrun deploy --force`
|
|
75
|
+
applies over a running flow when you mean it.
|
|
76
|
+
|
|
77
|
+
## "missing `type:` — OKF requires a non-empty type on every concept"
|
|
78
|
+
|
|
79
|
+
A file under `knowledge/` has no `type:` in its frontmatter. Add one
|
|
80
|
+
(`type: Reference` is fine for a table or a list); the push is refused
|
|
81
|
+
until it is there.
|
|
82
|
+
|
|
83
|
+
## The run is parked and nobody knows
|
|
84
|
+
|
|
85
|
+
Check the account's `notify:` — a workspace that declared its own block
|
|
86
|
+
replaced the account's whole, and may have dropped `awaiting-approval`. The
|
|
87
|
+
dashboard banner shows every parked run across workspaces regardless.
|
|
88
|
+
|
|
89
|
+
## It ran on the wrong model
|
|
90
|
+
|
|
91
|
+
`model:` resolves nearest-wins: the step, then the flow, then the agent. A
|
|
92
|
+
flow with `model: fast` in its frontmatter runs every step on the fast tier
|
|
93
|
+
whatever each agent says. The run trace names which level won
|
|
94
|
+
(`model: haiku — flow`). Put `model:` on the step to lift one.
|
|
95
|
+
|
|
96
|
+
## The schedule fired more often than it should
|
|
97
|
+
|
|
98
|
+
When day-of-month and day-of-week are both restricted, cron ORs them.
|
|
99
|
+
`0 5 1-7 * 5` fires every Friday and every day of the first week. Use a
|
|
100
|
+
plain day of month for a monthly job.
|
|
101
|
+
|
|
102
|
+
## Approval emails have no links
|
|
103
|
+
|
|
104
|
+
The install has no `FOLDRUN_PUBLIC_URL`, or it points at an address that no
|
|
105
|
+
longer resolves. The worker logs why, once. Set it to the origin people
|
|
106
|
+
actually reach the install on.
|
|
107
|
+
|
|
108
|
+
## A step's file never appeared in Storage
|
|
109
|
+
|
|
110
|
+
The agent wrote to `outputs/` (the run's scratch, archived with the run) or
|
|
111
|
+
to a path relative to somewhere it was not. Deliverables go to
|
|
112
|
+
`workspace/storage/`; the run page's Out column shows what actually landed
|
|
113
|
+
and where.
|
|
114
|
+
|
|
115
|
+
## The browser came back with `[page rendered empty]`
|
|
116
|
+
|
|
117
|
+
The page loaded, but nothing was on it — and the reason is in the same run
|
|
118
|
+
log, one line above `page: <url>`: `page errors:` (an uncaught error in the
|
|
119
|
+
page's own script), `page console:` (what it logged as an error),
|
|
120
|
+
`requests failed:` (a script or an API call that never landed) or
|
|
121
|
+
`requests refused:` (one the server answered 4xx/5xx). A single-page app
|
|
122
|
+
that renders after load usually shows as none of these — give it a
|
|
123
|
+
`wait_for` selector. A blocked resource you asked to `block` is never
|
|
124
|
+
counted. For the whole picture, call again with `mode: network`: the page's
|
|
125
|
+
own status and redirect chain first, then every request it made.
|
|
126
|
+
|
|
127
|
+
## A browser action on `"@e4"` failed
|
|
128
|
+
|
|
129
|
+
The number came from the last `mode=aria` in the same `session`, and the
|
|
130
|
+
next call loaded the page fresh, so the tool looked for what the number
|
|
131
|
+
pointed at — its role and name — and the message says which of three things
|
|
132
|
+
happened:
|
|
133
|
+
|
|
134
|
+
- `nothing is numbered yet` — no `mode=aria` ran in this `session` first,
|
|
135
|
+
or it ran under a different `session` name. The numbers are per session.
|
|
136
|
+
- `is not on the page now` — the element is gone: a different page, a
|
|
137
|
+
signed-out view, a list that changed. Read it again with `mode=aria`.
|
|
138
|
+
- `the page has 3 of those now and had 2` — the same button appears a
|
|
139
|
+
different number of times than when it was numbered, so which one was
|
|
140
|
+
meant is a guess the tool will not make. Read it again with `mode=aria`.
|
|
141
|
+
|
|
142
|
+
In each case the fix is the same: take a fresh `mode=aria`
|
|
143
|
+
(`interactive=true` for just the controls) and use its numbers. An element
|
|
144
|
+
with no role and no text — a bare wrapper — cannot be found again at all;
|
|
145
|
+
use a CSS selector for it.
|
|
146
|
+
|
|
147
|
+
## The browser's output was cut at 18,000 characters
|
|
148
|
+
|
|
149
|
+
The cap is on what the model sees, not on what was kept. `mode: markdown`
|
|
150
|
+
writes all of it to `outputs/page.md`, `meta` to `outputs/meta.json`,
|
|
151
|
+
`table` to `outputs/tables.json`, `network` to `outputs/network.json`, an
|
|
152
|
+
`extract` step to `outputs/extracted.json` — the truncation line names the
|
|
153
|
+
file. Read the file in the next step, or narrow the call: `wait_for` a
|
|
154
|
+
specific section, `block="image,font,media"` so the page is text, or an
|
|
155
|
+
`extract` step whose rows are exactly what you wanted.
|
package/docs/versions.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Versions and releases
|
|
2
|
+
|
|
3
|
+
The hosted platform deploys itself whenever its code changes — there is no
|
|
4
|
+
release train and nobody decides "this is a release". Every deploy that comes
|
|
5
|
+
up healthy is one, and gets a name.
|
|
6
|
+
|
|
7
|
+
## The scheme
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
v2026.10.01.3
|
|
11
|
+
│ │ │ └─ the third deploy that day
|
|
12
|
+
│ │ └──── day (UTC)
|
|
13
|
+
│ └─────── month
|
|
14
|
+
└──────────── year
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
CalVer with a daily counter, not semver. A box that ships every push to main
|
|
18
|
+
would have a bot bumping a patch number forever, and the numbers would mean
|
|
19
|
+
nothing; a date says when, and sorts. A rollback redeploys an older version
|
|
20
|
+
under its own name — `v2026.09.30.2` deployed again is still `v2026.09.30.2`.
|
|
21
|
+
|
|
22
|
+
Behind each name are the commits of the parts that make up the platform —
|
|
23
|
+
`core` (the runtime), `platform` (queue, worker, storage, billing), `web` (the
|
|
24
|
+
dashboard and the API), `docs` and `infra` — recorded when it was deployed.
|
|
25
|
+
The `foldrun` CLI and `@foldrun/core` on npm are packages a person publishes,
|
|
26
|
+
and keep ordinary semver (`0.6.0`).
|
|
27
|
+
|
|
28
|
+
## Where to see it
|
|
29
|
+
|
|
30
|
+
| Where | What |
|
|
31
|
+
|---|---|
|
|
32
|
+
| The sidebar's foot | `foldrun v2026.10.01.3`, linking to What's new |
|
|
33
|
+
| **What's new** (`/dashboard/whats-new`) | every recent release, newest first, with what changed in each — grouped Features, Fixes, Docs and Other |
|
|
34
|
+
| **Settings → About** | the version, when it was released, the API version, and each component's commit |
|
|
35
|
+
| `GET /api/version` | the same as JSON, no key needed — see the [API reference](api#versions) |
|
|
36
|
+
| `GET /api/changelog` | the release notes as JSON, with a key |
|
|
37
|
+
| Any `/api` response | the `X-Foldrun-Version`, `X-Foldrun-Api` and `X-Foldrun-Cli` headers |
|
|
38
|
+
| `foldrun version` | this CLI, its core, and the platform it talks to |
|
|
39
|
+
|
|
40
|
+
An open dashboard tab checks every few minutes, and when you come back to it,
|
|
41
|
+
whether the platform has moved on. If it has, a small notice offers a reload
|
|
42
|
+
and a link to What's new. It never reloads by itself.
|
|
43
|
+
|
|
44
|
+
## Release notes
|
|
45
|
+
|
|
46
|
+
The deploy writes them: for each release, the commits between the version
|
|
47
|
+
before and this one, in every part, grouped from what each commit says —
|
|
48
|
+
Features, Fixes, Docs (anything in the docs, or that says it is docs) and
|
|
49
|
+
Other (dependencies, tests, the deploy's own plumbing). The groups are read
|
|
50
|
+
from the words of a commit subject, so a fix described without the word may
|
|
51
|
+
land under Features. A release whose changes could not be read says so
|
|
52
|
+
rather than showing an empty list.
|
|
53
|
+
|
|
54
|
+
A self-hosted or locally built install has no notes and reports `dev`, or
|
|
55
|
+
whatever `FOLDRUN_VERSION` it was started with.
|
|
56
|
+
|
|
57
|
+
## The API version
|
|
58
|
+
|
|
59
|
+
`api` in `/api/version`, and the `X-Foldrun-Api` header, is a date —
|
|
60
|
+
`2026-10-01` — that changes only when a route changes in a way an existing
|
|
61
|
+
caller would break on. A new route or a new field in an answer does not move
|
|
62
|
+
it. Breaking changes are announced in the release notes of the version that
|
|
63
|
+
makes them.
|
|
64
|
+
|
|
65
|
+
## CLI compatibility
|
|
66
|
+
|
|
67
|
+
The CLI talks to the platform over the same HTTP API as everything else, so
|
|
68
|
+
an older CLI keeps working against a newer platform; what it lacks are the
|
|
69
|
+
newest commands. Each platform version records the CLI released with it
|
|
70
|
+
(`packages.cli` in `/api/version`, and `X-Foldrun-Cli` on every response):
|
|
71
|
+
|
|
72
|
+
- `foldrun version` compares that with its own version and warns when the
|
|
73
|
+
platform's is newer.
|
|
74
|
+
- Any other command that reaches the platform prints one dim line when the
|
|
75
|
+
platform's CLI is newer — at most once a day, only in a terminal, and
|
|
76
|
+
never in a script or CI. `FOLDRUN_NO_UPDATE_NOTICE=1` turns it off.
|
|
77
|
+
- `foldrun --version` prints the CLI's version and nothing else, offline.
|
|
78
|
+
|
|
79
|
+
To update: `npm i -g foldrun@latest`.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Workspaces
|
|
2
|
+
|
|
3
|
+
A workspace is a folder, and the folder is the unit of everything: it is what
|
|
4
|
+
you edit, deploy, permission, budget and back up. An account holds several —
|
|
5
|
+
one per job, in practice — and they share nothing unless it is put in the
|
|
6
|
+
account's library on purpose.
|
|
7
|
+
|
|
8
|
+
## The layout
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
my-desk/
|
|
12
|
+
AGENTS.md context every agent here sees, and the workspace's defaults
|
|
13
|
+
agents/<name>/ one folder per role
|
|
14
|
+
agent.md frontmatter, then the prompt
|
|
15
|
+
knowledge/ given to this agent only
|
|
16
|
+
memory/ what this agent learned
|
|
17
|
+
outputs/ this step's scratch — archived with the run
|
|
18
|
+
scripts/ code this agent's tools run
|
|
19
|
+
flows/<name>.md a numbered list of steps
|
|
20
|
+
tools/<name>.md what may be called — an API, a script, an MCP server
|
|
21
|
+
skills/<name>/ a capability, in the open Agent Skills format
|
|
22
|
+
evals/<name>.md tests
|
|
23
|
+
knowledge/ given to every agent in the workspace
|
|
24
|
+
memory/ what they learned, shared
|
|
25
|
+
state/ what the next run needs from this one
|
|
26
|
+
storage/ files a person reads or downloads
|
|
27
|
+
scripts/ code shared by this workspace's tools
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Every one of those is optional except `AGENTS.md` and at least one agent.
|
|
31
|
+
|
|
32
|
+
## The account around it
|
|
33
|
+
|
|
34
|
+
On the platform a workspace never stands alone: it lives under an account,
|
|
35
|
+
beside the account's own `AGENTS.md` and the library every workspace there
|
|
36
|
+
shares.
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
my-account/
|
|
40
|
+
AGENTS.md config and context every workspace here inherits
|
|
41
|
+
library/ tools, skills, scripts, knowledge, memory — shared
|
|
42
|
+
workspaces/
|
|
43
|
+
my-desk/ the tree above
|
|
44
|
+
ads-desk/
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`foldrun init` makes exactly that on a laptop, and `foldrun new <name>` adds
|
|
48
|
+
another workspace to it, so the folder you edit is the folder that runs. See
|
|
49
|
+
[the CLI reference](cli#the-shape-of-a-folder) for the commands that act on the
|
|
50
|
+
whole account — `check`, `deploy`, `pull`, `status`, `workspaces` — and for the
|
|
51
|
+
one scope that has no API: the account's own `AGENTS.md` is not pushed or
|
|
52
|
+
pulled, only edited in Settings.
|
|
53
|
+
|
|
54
|
+
A single folder with `agents/` and `flows/` at its root is still a workspace
|
|
55
|
+
and still works everywhere; `foldrun init --flat` makes one.
|
|
56
|
+
|
|
57
|
+
## `AGENTS.md` — context and defaults
|
|
58
|
+
|
|
59
|
+
The body is prose every agent in the workspace sees before its own prompt.
|
|
60
|
+
Put the things that are true of the whole desk there: the business, the
|
|
61
|
+
standing rules, what the reader is like.
|
|
62
|
+
|
|
63
|
+
The frontmatter is the workspace's defaults:
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
---
|
|
67
|
+
timezone: Australia/Sydney
|
|
68
|
+
budget: 60 # a cap in USD for this workspace — per month; or 60/day, 60/week; unset is no limit
|
|
69
|
+
notify:
|
|
70
|
+
email: ops@example.com
|
|
71
|
+
events: [failed, awaiting-approval, completed]
|
|
72
|
+
provider: # see Providers
|
|
73
|
+
base_url: https://openrouter.ai/api/v1
|
|
74
|
+
token: ${OPENROUTER_API_KEY}
|
|
75
|
+
---
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
There is an `AGENTS.md` one level up too — the account's — and the two
|
|
79
|
+
compose in a way worth learning once:
|
|
80
|
+
|
|
81
|
+
- **Prose accumulates.** The account's body is added to every workspace's,
|
|
82
|
+
so a rule written at the account cannot be dropped below it.
|
|
83
|
+
- **A frontmatter key replaces whole.** A workspace that sets `notify:`
|
|
84
|
+
replaces the account's `notify:` entirely — it does not merge into it. To
|
|
85
|
+
inherit a key, say nothing about it.
|
|
86
|
+
|
|
87
|
+
The second rule is the one that surprises people: a workspace that declares
|
|
88
|
+
its own `notify:` block silently stops receiving the account's default.
|
|
89
|
+
|
|
90
|
+
### The clock, all the way down
|
|
91
|
+
|
|
92
|
+
`timezone:` is the one default with levels below the workspace as well as
|
|
93
|
+
above it, because a flow's schedule and an agent's own calendar are both real
|
|
94
|
+
things to set. Nearest wins, and every level inherits the one above it unless
|
|
95
|
+
it says otherwise:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
agent frontmatter → flow frontmatter → workspace AGENTS.md →
|
|
99
|
+
account AGENTS.md → FOLDRUN_TIMEZONE → UTC
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Whichever level wins sets `TZ`, the date in the agent's prompt, and
|
|
103
|
+
`$FOLDRUN_DATE` in its scripts and its `verify:` shell — so "today" means the
|
|
104
|
+
same thing to every part of a step. Each step's trace names the zone and the
|
|
105
|
+
level it came from.
|
|
106
|
+
|
|
107
|
+
The value is an IANA name (`Australia/Sydney`) or a plain fixed offset —
|
|
108
|
+
`UTC+10`, `GMT-5`, `+10:00`, `-05:30`, or a bare `UTC`. `foldrun check` and a
|
|
109
|
+
deploy both refuse anything else; a bad value that reaches a run falls through
|
|
110
|
+
to the next level with one line in the trace rather than failing the step.
|
|
111
|
+
|
|
112
|
+
## The account library
|
|
113
|
+
|
|
114
|
+
`<account>/library/` holds tools, skills, knowledge and memory shared by every
|
|
115
|
+
workspace. Resolution is nearest-wins: an agent's own file beats the
|
|
116
|
+
workspace's, which beats the library's. So a shared integration — the tool
|
|
117
|
+
that clones your website, the skill that explains how — is defined once, and
|
|
118
|
+
a workspace that needs a different version shadows it by defining the same
|
|
119
|
+
name locally.
|
|
120
|
+
|
|
121
|
+
From inside a run the library is read-only, reached as `account/…`
|
|
122
|
+
(`account/knowledge/prices.md`). The Library page in the dashboard lists,
|
|
123
|
+
for every shared file, which agents use it and where a nearer copy overrides
|
|
124
|
+
it — that list is the blast radius of changing it.
|
|
125
|
+
|
|
126
|
+
## Where a run's files go
|
|
127
|
+
|
|
128
|
+
Three directories look alike and are not:
|
|
129
|
+
|
|
130
|
+
| directory | who reads it next | survives a deploy | example |
|
|
131
|
+
|---|---|---|---|
|
|
132
|
+
| `outputs/` | this step, and the archive | no — it is the run's | a draft, a fetched page |
|
|
133
|
+
| `storage/` | a person | yes | the weekly report, a CSV, an image |
|
|
134
|
+
| `state/` | the next run | yes, and a deploy never overwrites it | a cursor, an append-only history |
|
|
135
|
+
|
|
136
|
+
The test is not "is it important", it is **who reads it next**. A value
|
|
137
|
+
regenerated every run is `storage/`; a value accumulated across runs is
|
|
138
|
+
`state/`. From an agent, write `workspace/storage/x.md` and
|
|
139
|
+
`workspace/state/x.md` — the older `../../storage/x.md` is the same place. See [Storage and sharing](storage-and-sharing).
|
|
140
|
+
|
|
141
|
+
## What a deploy touches
|
|
142
|
+
|
|
143
|
+
A deploy — `foldrun deploy`, or a `git push` to the workspace's remote —
|
|
144
|
+
replaces the source tree: agents, flows, tools, skills, evals, knowledge,
|
|
145
|
+
`AGENTS.md`. It **never** touches `runs/`, `state/`, `secrets.json`, or any
|
|
146
|
+
memory an agent wrote that your push does not mention. Those belong to the
|
|
147
|
+
platform, not to git, and a deploy that reverted what an agent learned would
|
|
148
|
+
make every run a little dumber.
|
|
149
|
+
|
|
150
|
+
A push while a run is in flight is accepted and applied when the run
|
|
151
|
+
finishes; git tells you so at push time. A run parked at an approval gate
|
|
152
|
+
counts as in flight. See [Deploying](deploying).
|
|
153
|
+
|
|
154
|
+
## Previews
|
|
155
|
+
|
|
156
|
+
Push a branch instead of `main` and the platform deploys a copy of the
|
|
157
|
+
workspace named `<workspace>-preview-<branch>` from that branch's tree, runs
|
|
158
|
+
its evals there, and never fires its schedules. It reads the source
|
|
159
|
+
workspace's secrets. Deleting the branch deletes the preview. It is how a
|
|
160
|
+
change to a live desk gets tried without touching the live desk.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "foldrun",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Agents are just folders. Write them, check them, run them — on your machine.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -11,18 +11,22 @@
|
|
|
11
11
|
"node": ">=22"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@foldrun/core": "^0.
|
|
14
|
+
"@foldrun/core": "^0.6.0"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"bin",
|
|
18
18
|
"src",
|
|
19
|
-
"README.md"
|
|
19
|
+
"README.md",
|
|
20
|
+
"docs"
|
|
20
21
|
],
|
|
21
22
|
"scripts": {
|
|
22
23
|
"e2e": "FOLDRUN_E2E=1 FOLDRUN_DATA=$(mktemp -d /tmp/foldrun-e2e-XXXXXX) node --test --test-timeout=300000 tests/e2e.test.ts",
|
|
23
|
-
"test": "FOLDRUN_DATA=$(mktemp -d /tmp/foldrun-test-XXXXXX) node --test tests/cli-secrets.test.ts tests/cli-check-library.test.ts tests/cli-connect.test.ts tests/cli-accounts.test.ts tests/cli-remote.test.ts tests/cli-stream.test.ts tests/cli-doctor.test.ts",
|
|
24
|
+
"test": "FOLDRUN_DATA=$(mktemp -d /tmp/foldrun-test-XXXXXX) node --test tests/cli-account.test.ts tests/model-credential.test.ts tests/cli-approvals.test.ts tests/cli-stop.test.ts tests/cli-account-settings.test.ts tests/cli-schedule.test.ts tests/cli-billing.test.ts tests/cli-storage.test.ts tests/cli-scaffold.test.ts tests/cli-secrets.test.ts tests/cli-site-login.test.ts tests/cli-check-library.test.ts tests/cli-check-timezone.test.ts tests/cli-check-subagents.test.ts tests/cli-connect.test.ts tests/cli-accounts.test.ts tests/cli-remote.test.ts tests/cli-stream.test.ts tests/cli-doctor.test.ts tests/cli-tool-test.test.ts tests/cli-agent-run.test.ts tests/cli-check-remote.test.ts tests/cli-shares.test.ts tests/cli-triggers.test.ts tests/cli-providers.test.ts tests/cli-rerun-put.test.ts tests/cli-guide.test.ts tests/cli-runtimes.test.ts tests/cli-deploy-safety.test.ts tests/cli-operator.test.ts tests/cli-flow-patterns.test.ts tests/cli-flow-rm-step.test.ts tests/cli-flow-dup-step.test.ts tests/cli-flow-write-stale.test.ts tests/cli-agent-link-stale.test.ts tests/cli-parity.test.ts tests/cli-invoke-inputs.test.ts tests/cli-audit-keys.test.ts tests/cli-version.test.ts tests/cli-check-web-warnings.test.ts tests/cli-report-image.test.ts tests/cli-check-workspace-paths.test.ts tests/cli-parity-dashboard.test.ts tests/cli-api-standards.test.ts tests/cli-backups-onboarding.test.ts tests/cli-check-limits.test.ts tests/cli-gallery.test.ts tests/cli-status-platform.test.ts tests/cli-webhooks-notifications.test.ts",
|
|
24
25
|
"release": "node scripts/release.mjs",
|
|
25
|
-
"typecheck": "tsc -p tsconfig.json"
|
|
26
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
27
|
+
"docs:sync": "node scripts/sync-docs.mjs",
|
|
28
|
+
"prepack": "node scripts/sync-docs.mjs --check",
|
|
29
|
+
"prepare": "(test ! -f .githooks/install.sh || sh .githooks/install.sh)"
|
|
26
30
|
},
|
|
27
31
|
"repository": {
|
|
28
32
|
"type": "git",
|