cherry-works 0.5.0 → 0.6.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 +114 -20
- package/dist/cw.js +15 -15
- package/dist/main.js +64911 -4761
- package/dist/portal/main.js +49 -49
- package/dist/portal/styles.css +1 -1
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -115,12 +115,16 @@ Each kind comes up at a different time:
|
|
|
115
115
|
| `guide` | a touched file matches one of its `globs`, or on every turn when it has no globs |
|
|
116
116
|
| `sensor` | the `signal` it names is raised, and the harness runs its `run` command |
|
|
117
117
|
| `skill` | one of its `triggers` matches the request, or it is called by name as `/<id>` |
|
|
118
|
-
| `playbook` | one of its `triggers` matches
|
|
118
|
+
| `playbook` | one of its `triggers` matches, or it is called as `/<id>`; its body is a sequence of skills |
|
|
119
119
|
| `agent` | it is spawned by its id, with only the `tools` it lists |
|
|
120
120
|
| `posture` | always, wherever the host can be told what to `allow` and `deny` |
|
|
121
121
|
| `corpus` | a primitive's `rationale` cites it, to give the reasoning behind a rule |
|
|
122
122
|
| `mixin` | never on its own; its body is lent to the primitives that pull it in |
|
|
123
|
-
| `mcp` | a primitive's body names it as `[[<id>]]`:
|
|
123
|
+
| `mcp` | a primitive's body names it as `[[<id>]]`: an mcp origin outside the repository, reached through `cw mcp serve` |
|
|
124
|
+
|
|
125
|
+
A skill or a playbook that is only a step of another can say
|
|
126
|
+
`disable-user-invocation: true`: it is then not offered as a `/` command, and
|
|
127
|
+
the agent still opens it when its triggers match or a playbook sends it there.
|
|
124
128
|
|
|
125
129
|
`cw kinds <kind>` gives the exact fields each kind takes. An id names exactly
|
|
126
130
|
one primitive across the whole charter, whatever its kind. If two files claim
|
|
@@ -151,12 +155,15 @@ agent reads it.
|
|
|
151
155
|
| `cw remove <id> [--yes]` | Delete a primitive this repository authored |
|
|
152
156
|
| `cw explain <id>` | Show which file declares an id, what it pulls in and which tests name it |
|
|
153
157
|
| `cw doctor` | Check the agents, the charter, the vendor sources and the compiled output |
|
|
158
|
+
| `cw context [--exact]` | Say how many tokens the charter puts into the agent's context when a session opens |
|
|
159
|
+
| `cw sessions [--since] [--until] [--json]` | Sum up the tokens of the sessions kept on this machine, by day and by session |
|
|
154
160
|
| `cw test` | Run every case in `.cw/test/` against the charter |
|
|
161
|
+
| `cw eval` | Put every case in `.cw/eval/` to the real agent under promptfoo |
|
|
155
162
|
| `cw suite add \| edit \| remove` | Manage test files |
|
|
156
163
|
| `cw vendor add <source> [--ref] \| remove \| list` | Install, update, remove or list vendor sources |
|
|
157
164
|
| `cw portal [--port]` | Open the charter in a browser on this machine |
|
|
158
|
-
| `cw mcp auth [id] [--status]` | Sign in, as yourself, to every
|
|
159
|
-
| `cw mcp serve` | Serve every
|
|
165
|
+
| `cw mcp auth [id] [--status]` | Sign in, as yourself, to every mcp origin the charter reaches, or to one again |
|
|
166
|
+
| `cw mcp serve` | Serve every mcp origin the charter reaches to your agent, over stdio |
|
|
160
167
|
|
|
161
168
|
`cw doctor` exits with a failure status when the charter has an error, when a
|
|
162
169
|
vendored file was edited in this repository, or when the compiled output no
|
|
@@ -216,15 +223,95 @@ one:
|
|
|
216
223
|
{
|
|
217
224
|
"description": "The TypeScript guide comes up on source files.",
|
|
218
225
|
"cases": [
|
|
219
|
-
{ "do": { "touchFile": "src/one.ts" }, "expect": { "activate": "
|
|
220
|
-
{ "when": "Stop", "expect": { "run": "
|
|
226
|
+
{ "do": { "touchFile": "src/one.ts" }, "expect": { "activate": "no-any" } },
|
|
227
|
+
{ "when": "Stop", "expect": { "run": "lint" } },
|
|
221
228
|
{ "do": { "touchFile": ".env" }, "expect": { "allow": false } }
|
|
222
229
|
]
|
|
223
230
|
}
|
|
224
231
|
```
|
|
225
232
|
|
|
226
233
|
`cw test` resolves each case against the charter and reports the ones that no
|
|
227
|
-
longer hold.
|
|
234
|
+
longer hold. It runs no agent and costs nothing, so it fits in CI.
|
|
235
|
+
|
|
236
|
+
## Evaluating against the real agent
|
|
237
|
+
|
|
238
|
+
`cw test` proves what the charter says; `cw eval` proves what the agent does
|
|
239
|
+
with it. A file in `.cw/eval/` holds prompts and what is expected of each:
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"description": "Planning goes through the planning skill.",
|
|
244
|
+
"cases": [
|
|
245
|
+
{ "prompt": "plan this feature: export a report as PDF", "expect": { "invoke": "sdd-plan", "maxTokens": 200000 } },
|
|
246
|
+
{ "prompt": "add a function that totals an invoice", "expect": { "follow": "no-single-word-naming" } }
|
|
247
|
+
]
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Each case expects at least one of:
|
|
252
|
+
|
|
253
|
+
| Expectation | Passes when |
|
|
254
|
+
|---|---|
|
|
255
|
+
| `invoke: <id>` | the agent invoked that skill or playbook |
|
|
256
|
+
| `follow: <id>` | a model judge finds the agent followed that guide |
|
|
257
|
+
| `maxTokens: <n>` | the case used no more than that many tokens |
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
cw eval
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Every case is handed to [promptfoo](https://www.promptfoo.dev), which puts its
|
|
264
|
+
prompt to Claude Code run headless, in a worktree of your last commit with the
|
|
265
|
+
charter built, so your working tree is never touched. You never write a
|
|
266
|
+
promptfoo configuration. The first run installs promptfoo and the Claude Agent
|
|
267
|
+
SDK under `~/.cherry-works/promptfoo/`, and later runs reuse them.
|
|
268
|
+
|
|
269
|
+
The report gives each case's outcome and tokens, and the run's total. A case
|
|
270
|
+
that misses what it expects fails the run, with what the agent did instead.
|
|
271
|
+
It runs on whatever Claude Code is signed in with, or on `ANTHROPIC_API_KEY`
|
|
272
|
+
when set, and spends real tokens: commit before you run it, and keep the cases
|
|
273
|
+
few.
|
|
274
|
+
|
|
275
|
+
## What the charter costs
|
|
276
|
+
|
|
277
|
+
Everything the charter loads when a session opens — always-on guides, every
|
|
278
|
+
skill's description, every subagent's — is paid for on every turn.
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
cw context # each primitive's tokens, the largest first, estimated
|
|
282
|
+
cw context --exact # counted through the agent's own command line
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
A guide with `globs` is listed apart: it is loaded only when a file it names is
|
|
286
|
+
touched. `cw build` prints the total in one line, the portal shows the same
|
|
287
|
+
list, and `cw doctor` warns once the total passes `mainContextCeiling` in
|
|
288
|
+
`.cw/settings.json` (20,000 tokens unless you set it).
|
|
289
|
+
|
|
290
|
+
Once a session runs, the engine's own Stop hook counts what it has used, its
|
|
291
|
+
subagents included, each time the agent stops. It keeps one line per stop
|
|
292
|
+
under `~/.cherry-works/` (or the folder `sessionAnalysisFolder` names), never in
|
|
293
|
+
the repository, and tells you in one line each time a session crosses another
|
|
294
|
+
`sessionContextMark` tokens (100,000 unless you set it). The model is never
|
|
295
|
+
sent that line.
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
cw sessions # the last 31 days, by day and by session
|
|
299
|
+
cw sessions --since 2026-10-01 # 31 days from that day at most
|
|
300
|
+
cw sessions --since 2026-10-01 --until 2026-10-05 --json
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
To put a price on it, ask your agent what last week cost: the built-in
|
|
304
|
+
`cw-session-cost` skill reads the same summary, asks whether to use prices you
|
|
305
|
+
type or the provider's published ones, and answers per session and per day,
|
|
306
|
+
naming the prices it used.
|
|
307
|
+
|
|
308
|
+
```json
|
|
309
|
+
{
|
|
310
|
+
"agents": ["claude"],
|
|
311
|
+
"mainContextCeiling": 20000,
|
|
312
|
+
"sessionContextMark": 100000
|
|
313
|
+
}
|
|
314
|
+
```
|
|
228
315
|
|
|
229
316
|
## Vendor sources
|
|
230
317
|
|
|
@@ -246,13 +333,13 @@ Run `cw vendor add` again with a new `--ref` to update a source, and
|
|
|
246
333
|
|
|
247
334
|
| Charter | What it gives your agent | Install |
|
|
248
335
|
| --- | --- | --- |
|
|
249
|
-
| [sdd-charter](https://github.com/tamnguyenvt/sdd-charter) | Spec-driven development: a spec set with a status per story and a roadmap of their dependencies, and
|
|
336
|
+
| [sdd-charter](https://github.com/tamnguyenvt/sdd-charter) | Spec-driven development: a spec set with a status per story and a roadmap of their dependencies, and six commands (`/sdd-init`, `/sdd-plan`, `/sdd-implement`, `/sdd-bug-fix`, `/sdd-status`, `/sdd-report`) that take each story from request to merge, stopping for your yes at each step. | `cw vendor add git@github.com:tamnguyenvt/sdd-charter.git --ref v0.1.7` |
|
|
250
337
|
| [hexagonal-architecture-charter](https://github.com/tamnguyenvt/hexagonal-architecture-charter) | Sets up a hexagonal (ports and adapters) architecture in a folder you choose, then keeps the agent following it. | `cw vendor add git@github.com:tamnguyenvt/hexagonal-architecture-charter.git --ref v0.1.0` |
|
|
251
338
|
|
|
252
|
-
##
|
|
339
|
+
## MCP origins outside the repository
|
|
253
340
|
|
|
254
341
|
Much of what an agent needs to know is kept elsewhere: another service's code,
|
|
255
|
-
an issue tracker, a wiki. An `mcp` primitive declares one such
|
|
342
|
+
an issue tracker, a wiki. An `mcp` primitive declares one such mcp origin, an MCP
|
|
256
343
|
server, and the tools of it your agent may use:
|
|
257
344
|
|
|
258
345
|
```markdown
|
|
@@ -269,31 +356,38 @@ tools: ["get_file_contents", "search_code", "list_pull_requests"]
|
|
|
269
356
|
The billing service. Look here before changing anything that charges a customer.
|
|
270
357
|
```
|
|
271
358
|
|
|
272
|
-
|
|
359
|
+
An mcp origin is either an `endpoint` reached over HTTP, or a `command` with its
|
|
273
360
|
`args` that `cw` starts as a local process; a local one takes a token only, in
|
|
274
361
|
the environment variable its `tokenEnv` names. Any primitive points the agent
|
|
275
|
-
at
|
|
362
|
+
at an mcp origin by naming it in its body as `[[mfbs/billing]]`.
|
|
276
363
|
|
|
277
364
|
```bash
|
|
278
365
|
cw build # adds one entry, cw mcp serve, to your agent's .mcp.json
|
|
279
|
-
cw mcp auth # sign in to every
|
|
366
|
+
cw mcp auth # sign in to every mcp origin you are not signed in to yet
|
|
280
367
|
cw mcp auth --status
|
|
281
368
|
```
|
|
282
369
|
|
|
283
|
-
Every developer signs in as themselves, by browser where the
|
|
370
|
+
Every developer signs in as themselves, by browser where the mcp origin offers OAuth
|
|
284
371
|
or with a token typed at a hidden prompt. Credentials are kept in the operating
|
|
285
372
|
system's credential store, never in the repository, and renewed without asking
|
|
286
|
-
where the
|
|
287
|
-
given: it serves the tools each
|
|
288
|
-
your own credential.
|
|
373
|
+
where the mcp origin allows it. `cw mcp serve` is the one MCP server your agent is
|
|
374
|
+
given: it serves the tools each mcp origin declares and forwards every call under
|
|
375
|
+
your own credential. An mcp origin that is down or not signed in to loses only its own
|
|
289
376
|
tools.
|
|
290
377
|
|
|
291
|
-
|
|
292
|
-
|
|
378
|
+
The build asks each mcp origin for its tools once and keeps them beside the
|
|
379
|
+
charter, and turns your agent's own tool search on: a session opens with each
|
|
380
|
+
tool's name and no schema, and the agent looks up the one it needs. `cw mcp
|
|
381
|
+
serve` lists the kept tools without reaching any mcp origin, and reaches one
|
|
382
|
+
only for a call. A tool an `mcp` declares that its mcp origin does not list
|
|
383
|
+
stops the build.
|
|
384
|
+
|
|
385
|
+
A subagent reaches only the mcp origins it lists under `tools`: `[[<id>]]` for every
|
|
386
|
+
tool of an mcp origin, or `[[<id>]]:<tool>` for one of them.
|
|
293
387
|
|
|
294
388
|
## Your agent can write rules too
|
|
295
389
|
|
|
296
|
-
Every governed repository gets a built-in skill, `
|
|
390
|
+
Every governed repository gets a built-in skill, `cw-author`, in the
|
|
297
391
|
agent's hands from the moment `cw init` finishes. It teaches
|
|
298
392
|
the agent to ask `cw kinds` what a kind requires and to write primitives with
|
|
299
393
|
`cw add`, instead of copying fields from memory.
|
package/dist/cw.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "cherry-works",
|
|
6
|
-
version: "0.
|
|
6
|
+
version: "0.6.1",
|
|
7
7
|
description: "The charter engine: resolves a charter and compiles it into what a coding agent reads.",
|
|
8
8
|
keywords: [
|
|
9
9
|
"claude-code",
|
|
@@ -42,8 +42,8 @@ var package_default = {
|
|
|
42
42
|
scripts: {
|
|
43
43
|
build: "tsup && tailwindcss -i src/driver/portal/page/styles.css -o dist/portal/styles.css --minify",
|
|
44
44
|
typecheck: "tsc --noEmit && tsc --noEmit -p src/driver/portal/page",
|
|
45
|
-
test: 'pnpm run lint:deps && pnpm run build && node --import tsx --test "test/**/*.test.ts"',
|
|
46
|
-
cw: "node --import tsx main.ts",
|
|
45
|
+
test: 'pnpm run lint:deps && pnpm run build && node --import tsx --import ./scripts/moduleLoader.mjs --test "test/**/*.test.ts"',
|
|
46
|
+
cw: "node --import tsx --import ./scripts/moduleLoader.mjs main.ts",
|
|
47
47
|
"lint:deps": "depcruise src main.ts",
|
|
48
48
|
release: "node --import tsx scripts/release.ts",
|
|
49
49
|
prepublishOnly: `node -e "console.error('Publish with \\"pnpm release <version>\\", which checks the package first.'); process.exit(1)"`
|
|
@@ -54,6 +54,9 @@ var package_default = {
|
|
|
54
54
|
"@codemirror/language": "^6.12.4",
|
|
55
55
|
"@codemirror/state": "^6.7.4",
|
|
56
56
|
"@codemirror/view": "^6.43.11",
|
|
57
|
+
"@hono/node-server": "^2.1.1",
|
|
58
|
+
"@hono/zod-openapi": "^1.6.3",
|
|
59
|
+
"@modelcontextprotocol/sdk": "^1.31.0",
|
|
57
60
|
"@tailwindcss/cli": "^4.3.3",
|
|
58
61
|
"@tanstack/react-query": "^5.103.2",
|
|
59
62
|
"@types/node": "^22.10.2",
|
|
@@ -66,9 +69,14 @@ var package_default = {
|
|
|
66
69
|
clsx: "^2.1.1",
|
|
67
70
|
cmdk: "^1.1.1",
|
|
68
71
|
"dependency-cruiser": "^18.2.0",
|
|
72
|
+
hono: "^4.13.7",
|
|
73
|
+
"js-tiktoken": "^1.0.21",
|
|
69
74
|
"lucide-react": "^1.47.0",
|
|
70
75
|
marked: "^18.0.13",
|
|
76
|
+
picomatch: "^4.0.7",
|
|
71
77
|
playwright: "^1.63.0",
|
|
78
|
+
promptfoo: "0.123.1",
|
|
79
|
+
prompts: "^2.4.2",
|
|
72
80
|
"radix-ui": "^1.6.7",
|
|
73
81
|
react: "^19.3.0",
|
|
74
82
|
"react-dom": "^19.3.0",
|
|
@@ -78,23 +86,15 @@ var package_default = {
|
|
|
78
86
|
tsup: "^8.3.5",
|
|
79
87
|
tsx: "^4.19.2",
|
|
80
88
|
"tw-animate-css": "^1.4.0",
|
|
81
|
-
typescript: "^5.7.2"
|
|
89
|
+
typescript: "^5.7.2",
|
|
90
|
+
yaml: "^2.9.0",
|
|
91
|
+
yargs: "^18.1.0",
|
|
92
|
+
zod: "^4.6.1"
|
|
82
93
|
},
|
|
83
94
|
pnpm: {
|
|
84
95
|
onlyBuiltDependencies: [
|
|
85
96
|
"esbuild"
|
|
86
97
|
]
|
|
87
|
-
},
|
|
88
|
-
dependencies: {
|
|
89
|
-
"@hono/node-server": "^2.1.1",
|
|
90
|
-
"@hono/zod-openapi": "^1.6.3",
|
|
91
|
-
"@modelcontextprotocol/sdk": "^1.31.0",
|
|
92
|
-
hono: "^4.13.7",
|
|
93
|
-
picomatch: "^4.0.7",
|
|
94
|
-
prompts: "^2.4.2",
|
|
95
|
-
yaml: "^2.9.0",
|
|
96
|
-
yargs: "^18.1.0",
|
|
97
|
-
zod: "^4.6.1"
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
100
|
|