@netnodeag/kraftwerk 0.33.0 → 0.34.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/README.md +317 -242
- package/dist/cli/projects.js +30 -8
- package/dist/inspector/instances.d.ts +40 -0
- package/dist/inspector/instances.js +120 -1
- package/dist/inspector/server.js +18 -1
- package/inspector/dist/assets/{editor-BlAeAqt0.js → editor-CXrDJOv_.js} +3 -3
- package/inspector/dist/assets/{index-Dnqjpy0h.js → index-7J4zAS6J.js} +1 -1
- package/inspector/dist/assets/index-B7rwNdVj.css +1 -0
- package/inspector/dist/assets/index-BBGjdXk1.js +213 -0
- package/inspector/dist/assets/{index-e-11MUIo.js → index-BIDsfw8C.js} +1 -1
- package/inspector/dist/assets/{index--wwp-KD0.js → index-BNcXQYbv.js} +1 -1
- package/inspector/dist/assets/{index-BvCAG0mQ.js → index-BQMgADlc.js} +1 -1
- package/inspector/dist/assets/{index-AR7uGZPa.js → index-BULB2rC_.js} +1 -1
- package/inspector/dist/assets/{index-BKnMNAOc.js → index-Bumwg9SM.js} +1 -1
- package/inspector/dist/assets/{index-DcXZX6dj.js → index-BxEG-IdY.js} +1 -1
- package/inspector/dist/assets/{index--9LQl_DL.js → index-C3hpUVfp.js} +1 -1
- package/inspector/dist/assets/{index-LBoNKP4N.js → index-CMMYSoL3.js} +1 -1
- package/inspector/dist/assets/{index-D3O4auYk.js → index-CNJyAniG.js} +1 -1
- package/inspector/dist/assets/{index-9rElziKS.js → index-CUCCMUMY.js} +1 -1
- package/inspector/dist/assets/{index-C3ugp_Wf.js → index-ChuqpBnv.js} +1 -1
- package/inspector/dist/assets/{index-CdkhUV5I.js → index-CszaAR9T.js} +1 -1
- package/inspector/dist/assets/{index-CV4Aiss-.js → index-DAi1VtJ8.js} +1 -1
- package/inspector/dist/assets/{index-B0qGMqfM.js → index-DrSWAGft.js} +1 -1
- package/inspector/dist/assets/{index-BvGhLr64.js → index-Upf-BEsx.js} +1 -1
- package/inspector/dist/assets/{index-BxPjb1aG.js → index-x5G6Np7T.js} +1 -1
- package/inspector/dist/index.html +2 -2
- package/package.json +1 -1
- package/inspector/dist/assets/index-B7W4QbA2.css +0 -1
- package/inspector/dist/assets/index-C5IBvIVa.js +0 -213
package/README.md
CHANGED
|
@@ -6,23 +6,44 @@ knowledge, skills and workflows belong to the team, not to the person who
|
|
|
6
6
|
happened to set them up, and every result is checked before anyone relies on
|
|
7
7
|
it.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @netnodeag/kraftwerk # or run any command below via npx @netnodeag/kraftwerk
|
|
11
|
+
|
|
12
|
+
cd your-project
|
|
13
|
+
kraftwerk init # scaffold the workspace
|
|
14
|
+
kraftwerk doctor # check harnesses, docker, workflows, env vars
|
|
15
|
+
kraftwerk ui # open it at http://localhost:1981
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Needs Node 20+ and at least one agent harness (Claude Code, Codex, or Pi).
|
|
19
|
+
Details in [Install](#install).
|
|
20
|
+
|
|
21
|
+
**Why teams need it.** AI work today lives in individual silos. Personal
|
|
22
|
+
prompts, Claude Code sessions, one-off scripts. What one person figures out
|
|
23
|
+
stays with that person. Kraftwerk gives a team one place where that work
|
|
24
|
+
becomes shared practice.
|
|
25
|
+
|
|
26
|
+
- **Shared Agentic Workspace.** Prompts, sessions and scripts turn into
|
|
27
|
+
workflows, skills and knowledge that everyone can see, use and improve.
|
|
28
|
+
- **Persistent AI Coworkers.** Agents have a name, a role, a memory and
|
|
29
|
+
standing orders. They keep the knowledge they work with current, and every
|
|
30
|
+
conversation continues where the last one ended.
|
|
31
|
+
- **Combine agentic workflows with deterministic workflows.** Every agent step
|
|
32
|
+
has to pass a check that reads the actual files before the work moves on.
|
|
33
|
+
Each run leaves a trace of what happened, how long it took and what it cost.
|
|
34
|
+
- **RSI (Recursive Self-Improvement).** By default, all system components are
|
|
35
|
+
built around self-improving.
|
|
15
36
|
|
|
16
37
|
**What's in the workspace.**
|
|
17
38
|
|
|
18
|
-
- **Agents
|
|
19
|
-
and standing orders, running on Claude Code, Codex, Pi, and others
|
|
20
|
-
- **Knowledge
|
|
21
|
-
wiki, edited with autosave, verified by humans, exportable as PDF
|
|
22
|
-
- **Skills
|
|
23
|
-
- **Workflows
|
|
24
|
-
- **Verification
|
|
25
|
-
- **Inspector
|
|
39
|
+
- **Agents.** Persistent AI coworkers, each with its own identity, memory
|
|
40
|
+
and standing orders, running on Claude Code, Codex, Pi, and others.
|
|
41
|
+
- **Knowledge.** Shared organisational and project context, browsed like a
|
|
42
|
+
wiki, edited with autosave, verified by humans, exportable as PDF.
|
|
43
|
+
- **Skills.** Reusable capabilities and ways of working.
|
|
44
|
+
- **Workflows.** Repeatable multi-step processes.
|
|
45
|
+
- **Verification.** Gates that check the work against the files on disk.
|
|
46
|
+
- **Inspector.** The web UI that brings it all together.
|
|
26
47
|
|
|
27
48
|
This README is the reference for the framework and CLI. For the overview,
|
|
28
49
|
start at the [project README](https://github.com/NETNODEAG/kraftwerk#readme).
|
|
@@ -30,36 +51,77 @@ start at the [project README](https://github.com/NETNODEAG/kraftwerk#readme).
|
|
|
30
51
|
## Under the hood
|
|
31
52
|
|
|
32
53
|
Deterministic workflow-as-code over headless agent harnesses, in the spirit of
|
|
33
|
-
[super-simple-software-factory](https://github.com/disler/super-simple-software-factory)
|
|
34
|
-
|
|
35
|
-
|
|
54
|
+
[super-simple-software-factory](https://github.com/disler/super-simple-software-factory).
|
|
55
|
+
Code owns the control flow, agents work inside bounded phases. "Agent
|
|
56
|
+
proposes, code disposes."
|
|
57
|
+
|
|
58
|
+
Nothing binds to an SDK. Every agent phase spawns one short-lived CLI process
|
|
59
|
+
on the agent's harness, then judges the result afterwards against a typed JSON
|
|
60
|
+
envelope and file gates. Failed checks are corrected in the same session,
|
|
61
|
+
never by a cold restart. Every run leaves a `trace.jsonl` event log and ends
|
|
62
|
+
with a time, token and cost summary table.
|
|
63
|
+
|
|
64
|
+
## Install
|
|
65
|
+
|
|
66
|
+
You need Node 20 or newer and at least one agent harness on your PATH: Claude
|
|
67
|
+
Code (`claude`), Codex (`codex`), or Pi (`pi`). See [Harnesses](#harnesses)
|
|
68
|
+
for how to get them. `kraftwerk doctor` checks for all of it and names
|
|
69
|
+
whatever is missing.
|
|
36
70
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
71
|
+
Install it globally to get the `kraftwerk` command in every project:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm install -g @netnodeag/kraftwerk
|
|
75
|
+
kraftwerk --version
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Without installing, every command works prefixed with `npx`, at the cost of a
|
|
79
|
+
download per call:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx @netnodeag/kraftwerk --version
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Upgrading is the same command with `@latest`. A running inspector serves the
|
|
86
|
+
version it started with, so restart each UI afterwards. It offers a relaunch
|
|
87
|
+
by itself once a newer version is on disk.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm install -g @netnodeag/kraftwerk@latest
|
|
91
|
+
kraftwerk projects # every workspace on this machine, running or not
|
|
92
|
+
```
|
|
42
93
|
|
|
43
94
|
## Consume
|
|
44
95
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
96
|
+
Any repo with workflow folders under `workflows/` (or `src/workflows/`) is
|
|
97
|
+
already a complete consumer. No package.json, no local dependency, YAML
|
|
98
|
+
workflows only:
|
|
48
99
|
|
|
49
100
|
```bash
|
|
50
|
-
|
|
101
|
+
cd your-project
|
|
102
|
+
kraftwerk init # scaffold kraftwerk.yml + kraftwerk-data/ (workflow, agent, knowledge)
|
|
103
|
+
kraftwerk doctor # preflight: harness CLIs, docker, workflows, declared env vars
|
|
104
|
+
kraftwerk run hello "Was ist kraftwerk?"
|
|
105
|
+
kraftwerk ui # inspector on http://localhost:1981
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The same without a global install:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npx @netnodeag/kraftwerk init
|
|
51
112
|
npx @netnodeag/kraftwerk run hello "Was ist kraftwerk?"
|
|
113
|
+
npx @netnodeag/kraftwerk ui
|
|
52
114
|
```
|
|
53
115
|
|
|
54
|
-
Your own workflows are just more folders under `workflows
|
|
116
|
+
Your own workflows are just more folders under `workflows/`, each a
|
|
55
117
|
`workflow.yml` plus prompt files, discovered automatically (see
|
|
56
|
-
[YAML workflows](#yaml-workflows)). Or let a coding agent build one
|
|
118
|
+
[YAML workflows](#yaml-workflows)). Or let a coding agent build one.
|
|
57
119
|
`npx @netnodeag/kraftwerk create "<what it should do>"` prints a
|
|
58
|
-
self-contained brief that Claude Code
|
|
120
|
+
self-contained brief that Claude Code or Codex follows end to end.
|
|
59
121
|
|
|
60
|
-
For a local checkout
|
|
61
|
-
approval loops
|
|
62
|
-
short
|
|
122
|
+
For a local checkout or a programmatic consumer with TS workflows, custom
|
|
123
|
+
gates and approval loops, add the dependency. The `kraftwerk` alias keeps
|
|
124
|
+
imports short:
|
|
63
125
|
|
|
64
126
|
```jsonc
|
|
65
127
|
// package.json of your workflow project
|
|
@@ -70,14 +132,15 @@ short):
|
|
|
70
132
|
import { defineAgent, Run, runCli, fileNonEmpty, envelopeContract } from "kraftwerk";
|
|
71
133
|
```
|
|
72
134
|
|
|
73
|
-
##
|
|
135
|
+
## The kraftwerk CLI
|
|
74
136
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
137
|
+
The CLI ships with the package. Use `kraftwerk …` after a global install, or
|
|
138
|
+
`npx @netnodeag/kraftwerk …` anywhere without one. `npm link` in a dev
|
|
139
|
+
checkout also gives you the bare command. Workflows are auto-discovered under
|
|
140
|
+
`src/workflows/` (or `workflows/`), meaning every folder with a `workflow.yml`
|
|
141
|
+
and every top-level `.yml` file. Every command works from any subdirectory,
|
|
142
|
+
because the CLI walks up to the project root, marked by `kraftwerk.yml`, a
|
|
143
|
+
workflows root, or `.git`.
|
|
81
144
|
|
|
82
145
|
```bash
|
|
83
146
|
kraftwerk init # make this repo a consumer: kraftwerk.yml, workflows/, example
|
|
@@ -87,8 +150,9 @@ kraftwerk run # interactive: pick workflow, type the r
|
|
|
87
150
|
kraftwerk runs # past runs from output/*/trace.jsonl; runs show <id> for detail
|
|
88
151
|
kraftwerk knowledge # Context & Knowledge: OKF bundles (list/get/put/verify/search/...)
|
|
89
152
|
kraftwerk ui # inspector web UI on http://localhost:1981; --port, --output
|
|
153
|
+
kraftwerk projects # every workspace on this machine; projects start|stop|forget <ref>
|
|
90
154
|
kraftwerk doctor # preflight: harness CLIs, docker, workflows, declared env vars
|
|
91
|
-
kraftwerk validate # all discovered
|
|
155
|
+
kraftwerk validate # all discovered: schema + semantics + files, exit 1 on failure
|
|
92
156
|
kraftwerk validate src/workflows/pitch # specific paths
|
|
93
157
|
kraftwerk create "was der Workflow tun soll" # for LLM agents: prints a build brief
|
|
94
158
|
kraftwerk runner build # build the Docker sandbox image (once)
|
|
@@ -96,16 +160,16 @@ kraftwerk run --sandbox website-check "https://..." # isolated container per r
|
|
|
96
160
|
kraftwerk runner ps / stop <run-id> # see / stop running sandbox containers
|
|
97
161
|
```
|
|
98
162
|
|
|
99
|
-
###
|
|
163
|
+
### The kraftwerk.yml project config
|
|
100
164
|
|
|
101
|
-
Optional, at the project root
|
|
102
|
-
fields optional
|
|
103
|
-
directory
|
|
104
|
-
default `knowledge/`), and `agents:`
|
|
165
|
+
Optional, at the project root, and also the root marker for the walk-up. All
|
|
166
|
+
fields are optional. `workflows:` sets the workflows root, `output:` the
|
|
167
|
+
run-artifact directory (default `output/`), `knowledge:` the OKF bundle root
|
|
168
|
+
(default `knowledge/`), and `agents:` the team agent-definition root (default
|
|
105
169
|
`agents/`).
|
|
106
170
|
|
|
107
|
-
`switcher:` links other kraftwerk workspaces from the inspector header
|
|
108
|
-
|
|
171
|
+
`switcher:` links other kraftwerk workspaces from the inspector header. The
|
|
172
|
+
workspace name becomes a dropdown listing them:
|
|
109
173
|
|
|
110
174
|
```yaml
|
|
111
175
|
switcher:
|
|
@@ -114,67 +178,67 @@ switcher:
|
|
|
114
178
|
icon: "🛰" # optional
|
|
115
179
|
```
|
|
116
180
|
|
|
117
|
-
### Triggering from CI
|
|
181
|
+
### Triggering from CI, cron, or webhooks
|
|
118
182
|
|
|
119
|
-
`run --json` is the machine mode
|
|
120
|
-
on stdout (`ok`, `runDir`, per-phase stats, totals),
|
|
121
|
-
stderr. `KRAFTWERK_YES=1` equals `--yes`, `--quiet`
|
|
122
|
-
Exit codes: 0 ok, 2 usage
|
|
123
|
-
3 run failed (gate
|
|
183
|
+
`run --json` is the machine mode. It runs non-interactively, prints one JSON
|
|
184
|
+
result object on stdout (`ok`, `runDir`, per-phase stats, totals), and sends
|
|
185
|
+
all narration to stderr. `KRAFTWERK_YES=1` equals `--yes`, and `--quiet`
|
|
186
|
+
silences narration. Exit codes: 0 ok, 2 usage or config error (unknown
|
|
187
|
+
workflow, missing env), 3 run failed (gate, blocked, harness), 1 unexpected.
|
|
124
188
|
|
|
125
189
|
```bash
|
|
126
190
|
KRAFTWERK_YES=1 npx @netnodeag/kraftwerk run tagline "https://..." --json > result.json
|
|
127
191
|
```
|
|
128
192
|
|
|
129
193
|
Workflows declare the env vars they need via top-level `requires:
|
|
130
|
-
[MATOMO_TOKEN, ...]
|
|
131
|
-
`kraftwerk list` and `kraftwerk doctor
|
|
194
|
+
[MATOMO_TOKEN, ...]`. The engine checks them before anything spawns, and both
|
|
195
|
+
`kraftwerk list` and `kraftwerk doctor` list them.
|
|
132
196
|
|
|
133
|
-
### Remote workflows
|
|
197
|
+
### Remote workflows with --from
|
|
134
198
|
|
|
135
|
-
`list` and `run` accept `--from github:org/repo[@ref]
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
YOUR `output/`,
|
|
139
|
-
without vendoring:
|
|
199
|
+
`list` and `run` accept `--from github:org/repo[@ref]`, or any git URL. The
|
|
200
|
+
repo is shallow-cloned to `~/.cache/kraftwerk/remotes/`, refreshed per call
|
|
201
|
+
and cached for offline use, and its workflows run locally. Artifacts land in
|
|
202
|
+
YOUR `output/`, never in the cache. That way one workflow library serves many
|
|
203
|
+
projects without vendoring:
|
|
140
204
|
|
|
141
205
|
```bash
|
|
142
206
|
npx @netnodeag/kraftwerk run --from github:NETNODEAG/workflows tagline "https://..."
|
|
143
207
|
```
|
|
144
208
|
|
|
145
209
|
Sandbox mode (`--sandbox`) runs the workflow in a `kraftwerk-runner`
|
|
146
|
-
container
|
|
147
|
-
|
|
148
|
-
and artifacts appear live
|
|
149
|
-
`<project>/runner.env
|
|
150
|
-
pass-through
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
`run` prompts for whatever is missing
|
|
155
|
-
|
|
156
|
-
instead of breaking the listing. `create` is meant to be run BY an LLM
|
|
157
|
-
agent
|
|
158
|
-
example, gates, harness rules
|
|
159
|
-
author the workflow folder and validate
|
|
160
|
-
|
|
161
|
-
### Inspector on a server
|
|
162
|
-
|
|
163
|
-
The repo root ships [`deploy-starter/`](../deploy-starter/)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
basic-auth on top
|
|
169
|
-
runs coding agents against the mounted
|
|
170
|
-
the container persist in the `agent-home`
|
|
171
|
-
image from the `kraftwerk-runner` sandbox
|
|
172
|
-
`run --sandbox`.
|
|
173
|
-
|
|
174
|
-
##
|
|
175
|
-
|
|
176
|
-
The inspector's "team" screen turns chat agents into persistent teammates.
|
|
177
|
-
|
|
210
|
+
container, built from `runner/Dockerfile`. The workflow folder mounts
|
|
211
|
+
read-only. The run directory bind-mounts straight into the host `output/`, so
|
|
212
|
+
trace and artifacts appear live with no copy-back. Env vars come from
|
|
213
|
+
`<project>/runner.env`, plus `ANTHROPIC_API_KEY` and `OPENAI_API_KEY`
|
|
214
|
+
pass-through. `--run-id` pins the run folder name for external triggers, which
|
|
215
|
+
is what the inspector uses. `runner.json` in the run dir records container,
|
|
216
|
+
exit code, and timing.
|
|
217
|
+
|
|
218
|
+
`run` prompts for whatever is missing, both the workflow picker and the
|
|
219
|
+
request input. Invalid workflows show up red in `list` with their validation
|
|
220
|
+
error instead of breaking the listing. `create` is meant to be run BY an LLM
|
|
221
|
+
agent such as Claude Code or Codex. It prints a self-contained brief covering
|
|
222
|
+
the schema example, gates, harness rules and verify ladder, which the agent
|
|
223
|
+
follows to author the workflow folder and validate and smoke it with this CLI.
|
|
224
|
+
|
|
225
|
+
### Inspector on a server
|
|
226
|
+
|
|
227
|
+
The repo root ships [`deploy-starter/`](../deploy-starter/). Copy it into your
|
|
228
|
+
consumer repo as `deploy/` and it builds a small image, this package from npm
|
|
229
|
+
plus the claude, codex and pi CLIs, that serves `kraftwerk ui` for that repo
|
|
230
|
+
bind-mounted at `/work`. `compose.yml` is localhost-only, reachable over an
|
|
231
|
+
SSH tunnel. `compose.traefik.yml` layers traefik routing and mandatory
|
|
232
|
+
basic-auth on top. Treat that auth as load-bearing. The UI has no
|
|
233
|
+
authentication of its own and its chat runs coding agents against the mounted
|
|
234
|
+
repo. Agent logins made inside the container persist in the `agent-home`
|
|
235
|
+
volume. This is a different image from the `kraftwerk-runner` sandbox
|
|
236
|
+
(`runner/Dockerfile`) used by `run --sandbox`.
|
|
237
|
+
|
|
238
|
+
## Persistent team agents
|
|
239
|
+
|
|
240
|
+
The inspector's "team" screen turns chat agents into persistent teammates. A
|
|
241
|
+
team member is one folder under the project's `agents/` root:
|
|
178
242
|
|
|
179
243
|
```
|
|
180
244
|
agents/max/
|
|
@@ -187,7 +251,7 @@ agents/max/
|
|
|
187
251
|
name: Max
|
|
188
252
|
emoji: 🛠️
|
|
189
253
|
description: Runs and explains this project's workflows
|
|
190
|
-
harness: claude # claude | codex | pi
|
|
254
|
+
harness: claude # claude | codex | pi (which chat backend runs it)
|
|
191
255
|
model: sonnet # optional; harness default when omitted
|
|
192
256
|
effort: medium # optional: low | medium | high | xhigh | max
|
|
193
257
|
workflows: [tagline, website-check]
|
|
@@ -198,23 +262,26 @@ skills: [report-html] # optional allowlist; omit = all skills, [] = no
|
|
|
198
262
|
Sessions with a member are ordinary chats scoped `{ kind: "team", member }`,
|
|
199
263
|
listed per member in a second sidebar. On the first message the member gets
|
|
200
264
|
its role plus its connected workflows and knowledge bundles injected as
|
|
201
|
-
context
|
|
265
|
+
context. That context includes how to run workflows
|
|
202
266
|
(`KRAFTWERK_YES=1 npx kraftwerk run <workflow> "<request>"`) and how to read
|
|
203
|
-
and write knowledge through `kraftwerk knowledge
|
|
204
|
-
member's own actor, `<slug>/<harness
|
|
205
|
-
when a request matches and keeps its bundles current.
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
267
|
+
and write knowledge through `kraftwerk knowledge`, with writes stamped with
|
|
268
|
+
the member's own actor, `<slug>/<harness>`. So the member triggers its own
|
|
269
|
+
workflows when a request matches, and keeps its bundles current.
|
|
270
|
+
|
|
271
|
+
Model and effort ride on backend-specific channels. The claude adapter takes
|
|
272
|
+
the model via ACP session options and the thinking budget via
|
|
273
|
+
`MAX_THINKING_TOKENS`. Codex gets a `CODEX_CONFIG` env override (`model`,
|
|
274
|
+
`model_reasoning_effort`). Pi gets `--model` and `--thinking` flags. Members
|
|
275
|
+
are created and edited in the UI, or by editing the files, since the
|
|
276
|
+
definition is read fresh for each new session.
|
|
211
277
|
|
|
212
278
|
### Skills in chat
|
|
213
279
|
|
|
214
|
-
Chats
|
|
215
|
-
instruction packages, one folder per skill with a `SKILL.md`
|
|
216
|
-
frontmatter `name
|
|
217
|
-
roots, each shadowing same-named skills in the roots below
|
|
280
|
+
Chats, both general ones and team sessions, can use skills. These are
|
|
281
|
+
Claude-style instruction packages, one folder per skill with a `SKILL.md`
|
|
282
|
+
holding YAML frontmatter (`name`, `description`) and then the instructions.
|
|
283
|
+
Four roots are discovered, each shadowing same-named skills in the roots below
|
|
284
|
+
it:
|
|
218
285
|
|
|
219
286
|
```
|
|
220
287
|
<project>/agents/<slug>/skills/<name>/SKILL.md # private to that one team agent
|
|
@@ -223,26 +290,26 @@ roots, each shadowing same-named skills in the roots below it:
|
|
|
223
290
|
~/.claude/skills/<name>/SKILL.md # personal, per user
|
|
224
291
|
```
|
|
225
292
|
|
|
226
|
-
Agent skills are visible only to that agent's sessions and always apply
|
|
227
|
-
|
|
228
|
-
|
|
293
|
+
Agent skills are visible only to that agent's sessions and always apply. A
|
|
294
|
+
member's `skills:` allowlist narrows the shared roots only. Manage them in the
|
|
295
|
+
agent profile under "own skills", or by editing the files.
|
|
229
296
|
|
|
230
|
-
Every chat lists its visible skills as context
|
|
297
|
+
Every chat lists its visible skills as context under "## Your skills", so the
|
|
231
298
|
agent reaches for one when the request matches. Typing `/` in the composer
|
|
232
|
-
opens an autocomplete over them
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
### Routines
|
|
242
|
-
|
|
243
|
-
A member can have routines
|
|
244
|
-
an employee. Definitions live next to the member in
|
|
245
|
-
`agents/<slug>/routines.yml`
|
|
299
|
+
opens an autocomplete over them. Sending `/<name> <args>` expands the skill's
|
|
300
|
+
SKILL.md into the prompt, which is what makes this work identically on claude,
|
|
301
|
+
codex, and pi. On top of that, claude discovers `.claude/skills` natively (a
|
|
302
|
+
team member's `skills:` allowlist narrows that via ACP session options) and pi
|
|
303
|
+
loads each visible skill folder via `--skill`. Team members take an optional
|
|
304
|
+
`skills:` list in `agent.yml`. Omitted means all discovered skills, an empty
|
|
305
|
+
list means none, otherwise it is the allowlist. `GET /api/skills` returns
|
|
306
|
+
what's discovered.
|
|
307
|
+
|
|
308
|
+
### Routines, or scheduled prompts
|
|
309
|
+
|
|
310
|
+
A member can have routines, cron-scheduled prompts that work like standing
|
|
311
|
+
orders for an employee. Definitions live next to the member in
|
|
312
|
+
`agents/<slug>/routines.yml` and are git-tracked. Run state (last run, last
|
|
246
313
|
session, errors) lives in `<output>/routines-state.json`.
|
|
247
314
|
|
|
248
315
|
```yaml
|
|
@@ -256,25 +323,25 @@ session, errors) lives in `<output>/routines-state.json`.
|
|
|
256
323
|
enabled: true
|
|
257
324
|
```
|
|
258
325
|
|
|
259
|
-
The inspector server runs the scheduler in-process
|
|
260
|
-
due routine opens a fresh session for the member, posts
|
|
261
|
-
|
|
262
|
-
unattended, so tool-permission requests are auto-approved
|
|
263
|
-
request
|
|
264
|
-
prompts
|
|
265
|
-
routines on the member page
|
|
266
|
-
|
|
267
|
-
down are skipped, not replayed.
|
|
326
|
+
The inspector server runs the scheduler in-process, so there is no external
|
|
327
|
+
cron to set up. Every due routine opens a fresh session for the member, posts
|
|
328
|
+
the prompt, and shows up in the sessions sidebar titled "⏰ <name>". Routine
|
|
329
|
+
sessions run unattended, so tool-permission requests are auto-approved, with
|
|
330
|
+
the request and approval pair left in the thread as an audit trail. Give
|
|
331
|
+
routine prompts the same trust you would give a `KRAFTWERK_YES=1` workflow
|
|
332
|
+
run. Manage routines on the member page, where you can create, edit and
|
|
333
|
+
delete them, toggle enabled, hit "run now", and jump to the last run's
|
|
334
|
+
session. Schedules missed while the server is down are skipped, not replayed.
|
|
268
335
|
|
|
269
|
-
## Context & Knowledge
|
|
336
|
+
## Context & Knowledge
|
|
270
337
|
|
|
271
338
|
Alongside runs and chats, a project can keep curated knowledge as
|
|
272
339
|
[OKF v0.2](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
|
|
273
|
-
bundles
|
|
274
|
-
frontmatter under `knowledge/`, one concept per file. Human-readable,
|
|
275
|
-
agent-parseable, diffable in git
|
|
276
|
-
|
|
277
|
-
|
|
340
|
+
bundles, the Open Knowledge Format. A bundle is a directory of markdown files
|
|
341
|
+
with YAML frontmatter under `knowledge/`, one concept per file. Human-readable,
|
|
342
|
+
agent-parseable, diffable in git. The frontmatter describes itself: it carries
|
|
343
|
+
provenance (`sources`, `generated`), trust (`verified`), and lifecycle
|
|
344
|
+
(`status`, `stale_after`).
|
|
278
345
|
|
|
279
346
|
```
|
|
280
347
|
knowledge/
|
|
@@ -284,10 +351,10 @@ knowledge/
|
|
|
284
351
|
playbooks/refunds.md # a concept: YAML frontmatter + markdown body
|
|
285
352
|
```
|
|
286
353
|
|
|
287
|
-
The `kraftwerk knowledge` CLI is the enforced write path
|
|
288
|
-
`generated: { by, at }` with the writing actor, appends the bundle log,
|
|
289
|
-
|
|
290
|
-
|
|
354
|
+
The `kraftwerk knowledge` CLI is the enforced write path. `put` stamps
|
|
355
|
+
`generated: { by, at }` with the writing actor, appends the bundle log, and
|
|
356
|
+
regenerates the derived `index.md`, which is what keeps an agent-maintained
|
|
357
|
+
corpus trustable:
|
|
291
358
|
|
|
292
359
|
```bash
|
|
293
360
|
kraftwerk knowledge init customer-support # new bundle
|
|
@@ -302,18 +369,22 @@ kraftwerk knowledge fsck --fix # heal out-of-band edits
|
|
|
302
369
|
```
|
|
303
370
|
|
|
304
371
|
Actors follow the OKF convention: `<producer>/<version>` for agents,
|
|
305
|
-
`human:<id>` for people, `process:<id>` for automation. Consumers derive
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
372
|
+
`human:<id>` for people, `process:<id>` for automation. Consumers derive a
|
|
373
|
+
trust tier per concept from that:
|
|
374
|
+
|
|
375
|
+
- No `verified` field means unverified.
|
|
376
|
+
- Verified by a non-human actor means machine-confirmed.
|
|
377
|
+
- Verified by a `human:` actor means human-reviewed.
|
|
378
|
+
|
|
379
|
+
The inspector's Context & Knowledge screen shows bundles, concepts with
|
|
380
|
+
trust, status and staleness badges, sources, and the bundle log. The verify
|
|
381
|
+
button records a `human:user` verification. "Curate in chat" opens a
|
|
382
|
+
knowledge-scoped chat whose agent knows the OKF essentials and writes through
|
|
383
|
+
the CLI.
|
|
313
384
|
|
|
314
385
|
Workflows read and write knowledge through the same CLI via a
|
|
315
|
-
[CLI grant](#cli-grants)
|
|
316
|
-
|
|
386
|
+
[CLI grant](#cli-grants). The trust model stays intact because every agent
|
|
387
|
+
write is stamped with its actor:
|
|
317
388
|
|
|
318
389
|
```yaml
|
|
319
390
|
clis:
|
|
@@ -323,7 +394,7 @@ agents:
|
|
|
323
394
|
clis: [npx kraftwerk knowledge]
|
|
324
395
|
```
|
|
325
396
|
|
|
326
|
-
## The agent
|
|
397
|
+
## The agent's four axes
|
|
327
398
|
|
|
328
399
|
```ts
|
|
329
400
|
export const desloper = defineAgent({
|
|
@@ -334,7 +405,7 @@ export const desloper = defineAgent({
|
|
|
334
405
|
effort: "high", // optional: low | medium | high | xhigh | max
|
|
335
406
|
tools: ["Read", "Write", "Edit"], // governance: capability boundary
|
|
336
407
|
persona: `Du bist Lektor:in ...`, // WHO: the system prompt
|
|
337
|
-
clis: { // optional: CLI grants
|
|
408
|
+
clis: { // optional: CLI grants, the hint is injected
|
|
338
409
|
git: "Versionierung; nach jedem Schritt committen", // into the persona ONCE
|
|
339
410
|
},
|
|
340
411
|
mcp: { // optional: MCP servers (governance, like tools)
|
|
@@ -344,18 +415,18 @@ export const desloper = defineAgent({
|
|
|
344
415
|
```
|
|
345
416
|
|
|
346
417
|
The task arrives per phase, so one agent can serve several phases. Phases on
|
|
347
|
-
the same harness share one resumed session
|
|
348
|
-
far but always speaks with its own persona
|
|
349
|
-
share state through the run files only.
|
|
418
|
+
the same harness share one resumed session, where an agent sees the
|
|
419
|
+
conversation so far but always speaks with its own persona. Phases on
|
|
420
|
+
different harnesses share state through the run files only.
|
|
350
421
|
|
|
351
|
-
##
|
|
422
|
+
## Building blocks
|
|
352
423
|
|
|
353
|
-
|
|
|
424
|
+
| Building block | What it does |
|
|
354
425
|
| --------- | ------------ |
|
|
355
426
|
| `defineAgent` ([src/agent.ts](src/agent.ts)) | persona + model/effort + tools + harness |
|
|
356
|
-
| `Run.agentPhase({name, agent, prompt, gates})` ([src/run.ts](src/run.ts)) | spawn
|
|
427
|
+
| `Run.agentPhase({name, agent, prompt, gates})` ([src/run.ts](src/run.ts)) | spawn, parse envelope, run gates, correct in-session (bounded by `maxGateRetries`) |
|
|
357
428
|
| `Run.codePhase(name, fn)` | deterministic step, timed and traced |
|
|
358
|
-
| Gates ([src/gates.ts](src/gates.ts)) | post-execution file checks: `fileNonEmpty`, `slotsFilled`, `containsText
|
|
429
|
+
| Gates ([src/gates.ts](src/gates.ts)) | post-execution file checks: `fileNonEmpty`, `slotsFilled`, `containsText`, or your own `Gate` |
|
|
359
430
|
| Envelope ([src/envelope.ts](src/envelope.ts)) | every phase prompt ends with `envelopeContract(phase)`; `parseEnvelope` enforces it |
|
|
360
431
|
| Stats ([src/stats.ts](src/stats.ts)) | per-phase attempts/time/tokens/cost, `run.printSummary()` renders the table |
|
|
361
432
|
| `runCli(workflows)` ([src/cli.ts](src/cli.ts)) | registry CLI: `npm start -- <name> [--yes] [--verbose] "<request>"` |
|
|
@@ -375,20 +446,22 @@ same interface ([src/harness.ts](src/harness.ts)):
|
|
|
375
446
|
| Hermetic | `--setting-sources ""` | `--ignore-user-config` | `--no-context-files` |
|
|
376
447
|
| MCP | `--mcp-config` + `--strict-mcp-config`, allowlist `mcp__<name>` | `-c mcp_servers.*` + `--approve-for-me` (headless approvals) | not supported (own extension system) |
|
|
377
448
|
| CLIs | scoped allowlist `Bash(<name>:*)` | sandbox runs them anyway (hint only) | plain `bash` tool (no scoping) |
|
|
378
|
-
| Quirks |
|
|
449
|
+
| Quirks | none | no system-prompt flag (persona prepended to prompt); governance = workspace-write sandbox, not per-tool | `effort` maps 1:1 to `--thinking`; tool names lowercased |
|
|
450
|
+
|
|
451
|
+
Prerequisites per harness:
|
|
379
452
|
|
|
380
|
-
|
|
381
|
-
`brew install --cask codex`
|
|
382
|
-
@earendil-works/pi-coding-agent
|
|
383
|
-
subscription OAuth, other vendors need their key in
|
|
384
|
-
`pi auth check --provider deepseek`).
|
|
453
|
+
- **claude** needs Claude Code installed and logged in.
|
|
454
|
+
- **codex** needs `brew install --cask codex` and `codex login`.
|
|
455
|
+
- **pi** needs `npm install -g @earendil-works/pi-coding-agent`. Anthropic
|
|
456
|
+
models reuse the Claude subscription OAuth, other vendors need their key in
|
|
457
|
+
the env (check with `pi auth check --provider deepseek`).
|
|
385
458
|
|
|
386
459
|
## YAML workflows
|
|
387
460
|
|
|
388
|
-
Linear workflows can be pure config
|
|
389
|
-
`runs-on`, `${{ request }}` / `${{ agent }}
|
|
390
|
-
|
|
391
|
-
|
|
461
|
+
Linear workflows can be pure config, GitHub-Actions-flavored with `steps`,
|
|
462
|
+
`runs-on`, and `${{ request }}` / `${{ agent }}`. The canonical form is a
|
|
463
|
+
folder. `workflow.yml` holds agents and steps, long prompts live as files next
|
|
464
|
+
to it. Load it with `loadWorkflow(path)` and register it like any other
|
|
392
465
|
workflow:
|
|
393
466
|
|
|
394
467
|
```
|
|
@@ -421,25 +494,26 @@ steps:
|
|
|
421
494
|
- contains: { file: brand.md, text: "## Tonalitaet", label: Tonalitaet }
|
|
422
495
|
```
|
|
423
496
|
|
|
424
|
-
Running it needs no code at all
|
|
425
|
-
the folder. Programmatic registration works too:
|
|
497
|
+
Running it needs no code at all, because `kraftwerk run tagline "..."`
|
|
498
|
+
discovers the folder. Programmatic registration works too:
|
|
426
499
|
|
|
427
500
|
```ts
|
|
428
501
|
const tagline = await loadWorkflow(path.join(import.meta.dirname, "workflows/tagline"));
|
|
429
502
|
runCli({ [tagline.name]: tagline });
|
|
430
503
|
```
|
|
431
504
|
|
|
432
|
-
Single-line `prompt
|
|
433
|
-
inside the folder
|
|
434
|
-
with everything inline works too
|
|
435
|
-
agent id
|
|
436
|
-
`verdict-${{ agent }}.md
|
|
505
|
+
Single-line `prompt:`, `persona:` and `workspace:` values are file references
|
|
506
|
+
inside the folder. Multiline values stay inline, and a plain single `.yml`
|
|
507
|
+
file with everything inline works too. `${{ agent }}` interpolates the step's
|
|
508
|
+
agent id, so three jury steps can share one `prompts/assess.md` that writes
|
|
509
|
+
`verdict-${{ agent }}.md`, as the pitch workflow does. The engine appends the
|
|
437
510
|
envelope contract to every step prompt itself.
|
|
438
511
|
|
|
439
|
-
|
|
440
|
-
(
|
|
441
|
-
|
|
442
|
-
|
|
512
|
+
Validation runs against
|
|
513
|
+
[`schema/workflow.schema.json`](schema/workflow.schema.json), which is strict:
|
|
514
|
+
unknown keys are errors, and editors autocomplete via the
|
|
515
|
+
`# yaml-language-server: $schema=…` line. Semantic checks cover agent
|
|
516
|
+
references, duplicate steps, variables, and referenced files.
|
|
443
517
|
|
|
444
518
|
```bash
|
|
445
519
|
kraftwerk validate # all discovered workflows
|
|
@@ -447,17 +521,17 @@ kraftwerk validate src/workflows/tagline # specific paths
|
|
|
447
521
|
npm start -- validate <path> # runCli consumers (TS registry)
|
|
448
522
|
```
|
|
449
523
|
|
|
450
|
-
Gates: `file_non_empty: <file>`, `slots_filled: <file>`,
|
|
524
|
+
Gates come in four forms: `file_non_empty: <file>`, `slots_filled: <file>`,
|
|
451
525
|
`contains: {file, text, label?}`, and `check: <script>` (or
|
|
452
|
-
`check: {run, label?}`)
|
|
453
|
-
directory
|
|
454
|
-
becomes the failure message, verbatim in the correction prompt.
|
|
455
|
-
values reference a file inside the workflow folder, like `run:`.
|
|
456
|
-
|
|
457
|
-
Steps take an optional `if
|
|
458
|
-
forms as gates, evaluated against the run directory just before the step.
|
|
459
|
-
|
|
460
|
-
continues
|
|
526
|
+
`check: {run, label?}`). The last one is a bash validation script executed in
|
|
527
|
+
the run directory. Exit 0 passes. Non-zero fails, and everything the script
|
|
528
|
+
printed becomes the failure message, verbatim in the correction prompt.
|
|
529
|
+
Single-line values reference a file inside the workflow folder, like `run:`.
|
|
530
|
+
|
|
531
|
+
Steps take an optional `if:`, holding deterministic preconditions in the same
|
|
532
|
+
forms as gates, evaluated against the run directory just before the step. Any
|
|
533
|
+
unmet precondition skips the step, traced as `phase_skipped` while the run
|
|
534
|
+
continues. This is how you avoid spawning an agent when a previous script
|
|
461
535
|
found nothing to do:
|
|
462
536
|
|
|
463
537
|
```yaml
|
|
@@ -473,16 +547,16 @@ found nothing to do:
|
|
|
473
547
|
Living examples:
|
|
474
548
|
[`../agent-playground/src/workflows/tagline/`](../agent-playground/src/workflows/tagline/)
|
|
475
549
|
and [`../agent-playground/src/workflows/pitch/`](../agent-playground/src/workflows/pitch/);
|
|
476
|
-
`check
|
|
477
|
-
v1 is deliberately linear
|
|
478
|
-
stay on the roadmap
|
|
479
|
-
non-linear is a TS workflow.
|
|
550
|
+
`check` and `if` in [`../agent-playground/src/workflows/helpdesk-check/`](../agent-playground/src/workflows/helpdesk-check/).
|
|
551
|
+
v1 is deliberately linear. Approval loops and AGENTS.md-style context files
|
|
552
|
+
stay on the roadmap, and skills exist in chat rather than in workflow runs.
|
|
553
|
+
Anything non-linear is a TS workflow.
|
|
480
554
|
|
|
481
555
|
### MCP servers alongside the workflow
|
|
482
556
|
|
|
483
|
-
A workflow folder can carry its own MCP servers
|
|
484
|
-
|
|
485
|
-
|
|
557
|
+
A workflow folder can carry its own MCP servers, and agents opt in by name,
|
|
558
|
+
the same governance model as `tools`. Relative files resolve inside the
|
|
559
|
+
folder. Absolute paths and `url:` entries hook up external or remote servers:
|
|
486
560
|
|
|
487
561
|
```yaml
|
|
488
562
|
mcp:
|
|
@@ -498,20 +572,20 @@ agents:
|
|
|
498
572
|
mcp: [calculator] # this agent may use these servers
|
|
499
573
|
```
|
|
500
574
|
|
|
501
|
-
The stdio server is any MCP server
|
|
502
|
-
`server.tool(...)`
|
|
503
|
-
`package.json
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
575
|
+
The stdio server is any MCP server, for instance `@modelcontextprotocol/sdk`
|
|
576
|
+
with `server.tool(...)` and `StdioServerTransport`, its deps declared in the
|
|
577
|
+
consumer's `package.json`. On claude the servers are passed hermetically with
|
|
578
|
+
`--strict-mcp-config` and the allowlist gains `mcp__<name>`. On codex they
|
|
579
|
+
become `-c mcp_servers.*` overrides and the phase runs with `--approve-for-me`
|
|
580
|
+
so headless MCP calls get approved. Combining `runs-on: pi` with `mcp` is
|
|
581
|
+
rejected at validation time. Living example:
|
|
508
582
|
[`../agent-playground/src/workflows/rechner/`](../agent-playground/src/workflows/rechner/).
|
|
509
583
|
|
|
510
584
|
### CLI grants
|
|
511
585
|
|
|
512
|
-
For
|
|
513
|
-
once and grant per agent, so no step prompt has to
|
|
514
|
-
exist or how to call them:
|
|
586
|
+
For command-line tools that already exist, an MCP server is more than the job
|
|
587
|
+
needs. Declare them once and grant them per agent, so no step prompt has to
|
|
588
|
+
repeat which CLIs exist or how to call them:
|
|
515
589
|
|
|
516
590
|
```yaml
|
|
517
591
|
clis: # command prefix -> one-line usage hint
|
|
@@ -523,37 +597,38 @@ agents:
|
|
|
523
597
|
clis: [my, git] # this agent may call these via Bash
|
|
524
598
|
```
|
|
525
599
|
|
|
526
|
-
The hint is injected into the agent's persona ONCE
|
|
527
|
-
step prompts
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
(
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
600
|
+
The hint is injected into the agent's persona ONCE. That is the whole point,
|
|
601
|
+
since it keeps step prompts clean.
|
|
602
|
+
|
|
603
|
+
Each harness handles the grant differently. Claude also scopes the Bash
|
|
604
|
+
allowlist to `Bash(<name>:*)`, so the granted prefixes run headless without
|
|
605
|
+
approval while everything else keeps claude's default judgment, auto-approving
|
|
606
|
+
read-only commands and denying mutating ones. Codex needs nothing, because the
|
|
607
|
+
workspace-write sandbox runs commands anyway. Pi has no per-command scoping, so
|
|
608
|
+
a grant enables the plain `bash` tool.
|
|
534
609
|
|
|
535
610
|
## Used by
|
|
536
611
|
|
|
537
|
-
- [`../agent-playground/`](../agent-playground/)
|
|
538
|
-
the YAML example workflows
|
|
539
|
-
MCP server, `website-check` with script steps
|
|
540
|
-
- `nn-content-workflow-2`
|
|
541
|
-
outside this repo
|
|
542
|
-
|
|
543
|
-
revision loop.
|
|
612
|
+
- [`../agent-playground/`](../agent-playground/) is the in-repo consumer with
|
|
613
|
+
the YAML example workflows: `tagline`, `pitch`, `rechner` with its own
|
|
614
|
+
MCP server, and `website-check` with script steps.
|
|
615
|
+
- `nn-content-workflow-2` lives in the local `langgraph/` experiments folder
|
|
616
|
+
outside this repo. It generates the netnode.ch content board and Matomo
|
|
617
|
+
report, and shows the full ADW pattern including the engineer approval gate
|
|
618
|
+
and revision loop.
|
|
544
619
|
|
|
545
620
|
To scaffold a new workflow, use the repo-root skill `/new-workflow`.
|
|
546
621
|
|
|
547
622
|
## Developer
|
|
548
623
|
|
|
549
|
-
Source is TypeScript under `src
|
|
550
|
-
JavaScript
|
|
551
|
-
tsconfig.build.json
|
|
552
|
-
via `tsx` whenever `src/` is present
|
|
553
|
-
are always live, a stale `dist/` can never shadow them.
|
|
554
|
-
installs contain no `src/`, so they take the compiled `dist/` path.
|
|
555
|
-
`KRAFTWERK_DIST=1 kraftwerk …` forces `dist/` from the checkout,
|
|
556
|
-
|
|
624
|
+
Source is TypeScript under `src/`. The published package ships compiled
|
|
625
|
+
JavaScript and type declarations under `dist/`, built by
|
|
626
|
+
`tsc -p tsconfig.build.json`. The bin shim `bin/kraftwerk.js` runs the TS
|
|
627
|
+
source via `tsx` whenever `src/` is present, which covers a dev checkout and
|
|
628
|
+
`npm link`. Edits are always live, and a stale `dist/` can never shadow them.
|
|
629
|
+
Published installs contain no `src/`, so they take the compiled `dist/` path.
|
|
630
|
+
`KRAFTWERK_DIST=1 kraftwerk …` forces `dist/` from the checkout, which is
|
|
631
|
+
handy for verifying a fresh build.
|
|
557
632
|
|
|
558
633
|
```bash
|
|
559
634
|
npm run typecheck # tsc --noEmit over src/
|
|
@@ -570,11 +645,11 @@ npm link # global `kraftwerk` command from this checkout (no build ne
|
|
|
570
645
|
npm publish # runs npm run build first via prepublishOnly
|
|
571
646
|
```
|
|
572
647
|
|
|
573
|
-
The
|
|
574
|
-
|
|
575
|
-
`inspector/dist/` (the prebuilt web UI for `kraftwerk ui
|
|
576
|
-
`prepublishOnly
|
|
577
|
-
`dist/inspector/`)
|
|
578
|
-
|
|
579
|
-
`
|
|
580
|
-
|
|
648
|
+
The `files` field whitelists the tarball: `bin/`, `dist/`, `runner/` (the
|
|
649
|
+
Dockerfile for sandboxed runs), `schema/` (the workflow JSON schema), and
|
|
650
|
+
`inspector/dist/` (the prebuilt web UI for `kraftwerk ui`, built by
|
|
651
|
+
`prepublishOnly` and served by the dependency-free server compiled into
|
|
652
|
+
`dist/inspector/`). No `src/`, no examples. Check with `npm pack --dry-run`
|
|
653
|
+
before a release. Runtime deps stay regular `dependencies`, while `tsx`,
|
|
654
|
+
`typescript`, and the inspector's Vite and React toolchain are dev-only, so
|
|
655
|
+
consumers install none of them.
|