Skip to content

Commit 3ef7040

Browse files
feat: jev-nudge mod for Command Code
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
0 parents  commit 3ef7040

16 files changed

Lines changed: 2472 additions & 0 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: ci
2+
on: [push, pull_request]
3+
jobs:
4+
check:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- uses: actions/checkout@v4
8+
- uses: pnpm/action-setup@v4
9+
with:
10+
version: 10
11+
- uses: actions/setup-node@v4
12+
with:
13+
node-version: 22
14+
cache: pnpm
15+
- run: pnpm install --frozen-lockfile
16+
- run: pnpm lint
17+
- run: pnpm typecheck
18+
- run: pnpm test

‎.github/workflows/image.png‎

220 KB
Loading

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
jev-log.jsonl
3+
.commandcode

‎LICENSE‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Ahmad Awais
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎README.md‎

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# cmd-mod-jev-nudge
2+
3+
![cmd-mod-jev-nudge](https://raw.githubusercontent.com/CommandCodeAI/cmd-mod-jev-nudge/refs/heads/main/.github/workflows/image.png)
4+
5+
Agents stop too early. They finish one step, write "next I'll do X", and hand the prompt back.
6+
7+
This [Command Code](https://commandcode.ai) mod catches that. When a run is about to end, it asks
8+
[Jev](https://typesafe.ai) whether a nudge would help the agent keep working on what you asked for.
9+
Jev answers with a probability. A confident yes sends the agent back to work.
10+
11+
Two guards stop a bad nudge. One checks if the agent is waiting on you (permission, a decision,
12+
missing info). The other checks if the last nudge got anything done.
13+
14+
```
15+
model finishes turn (no tool calls)
16+
│
17+
▼
18+
onStop → state {user_requests, latest_assistant_message, recent_tool_calls, previous_nudges}
19+
│
20+
▼
21+
POST api.commandcode.ai/provider/v1/systemone ──► Jev
22+
nudge "would a gentle nudge help… right now?" → p
23+
waiting "needs permission / decision / info / event?" → p
24+
progress "moved on since the reply we nudged?" → p (2nd+ nudge only)
25+
│
26+
▼
27+
waiting ≥ .5 · progress < .5 · nudge < .5 · error/timeout ──► run stops as normal
28+
otherwise ──► {continue: true} + nudge turn ──► model keeps working
29+
(Command Code allows 8 of these per user turn, then ends the run)
30+
```
31+
32+
## Install
33+
34+
```bash
35+
cmd login # skip if signed in
36+
cmd mods add cmd-mod-jev-nudge # add -g for all projects
37+
```
38+
39+
That's it. The mod uses your Command Code key, from `CMD_API_KEY` or `cmd login`. With no
40+
key it stays off and says so. If Jev fails or times out, the run stops like it would without the mod.
41+
42+
## Flags
43+
44+
Pass with `--mod-option name=value`.
45+
46+
| Flag | Default | Meaning |
47+
|---|---|---|
48+
| `jev-nudge-threshold` | `0.5` | Minimum "a nudge would help" probability |
49+
| `jev-nudge-max` | none | Max nudges per run. `0` turns nudging off |
50+
| `jev-nudge-base-url` | `https://api.commandcode.ai` | API root, for a proxy or the fake server |
51+
| `jev-nudge-model` | `typesafe/jev` | Model id |
52+
| `jev-nudge-verbose` | `false` | Show declined stops in the feed too |
53+
54+
`DEBUG=true` prints every decision to stderr.
55+
56+
Why 0.5? I measured it. Jev says 0.5 to 0.8 when real work is left and 0.04 to 0.08 when the agent is
57+
done. 0.5 sits in the gap. At 0.6 the first nudge depended on how the model worded its status line.
58+
59+
Why no nudge cap by default? Stopping after N nudges without looking is the same "stopped too early"
60+
bug. The guards end runs on evidence instead. Command Code still caps stop-hook continues at 8 per
61+
user turn, and no mod can raise that. A task that needs more than 8 nudges should be split up anyway.
62+
63+
## Try it from a clone
64+
65+
```bash
66+
git clone git@github.com:CommandCodeAI/cmd-mod-jev-nudge.git
67+
cd cmd-mod-jev-nudge
68+
pnpm install # --mod doesn't install deps, cmd mods add does
69+
cmd --mod . # loads this mod for one session
70+
```
71+
72+
This prompt forces early stops on purpose:
73+
74+
```
75+
Five steps: (1) create smoke-1-ignite.txt containing ignite, (2) create smoke-2-kindle.txt
76+
containing kindle, (3) create smoke-3-blaze.txt containing blaze, (4) create smoke-4-ember.txt
77+
containing ember, (5) create smoke-5-ash.txt containing ash. Ignore any other files in the folder.
78+
Rule for this exercise: do exactly ONE step per reply, then end your reply with a short status
79+
line saying which steps remain. When all five files exist, say "all five files are done".
80+
```
81+
82+
One prompt, five replies. You type once. Percentages vary run to run.
83+
84+
```
85+
you ▸ Five steps: (1) create smoke-1-ignite.txt ...
86+
87+
agent ▸ write smoke-1-ignite.txt
88+
Created smoke-1-ignite.txt. Remaining: 2, 3, 4, 5.
89+
┊ stop → Jev: nudge 78% · waiting 6%
90+
jev nudge 1: unfinished work found (78%), continuing
91+
92+
agent ▸ write smoke-2-kindle.txt
93+
Created smoke-2-kindle.txt. Remaining: 3, 4, 5.
94+
┊ stop → Jev: nudge 74% · waiting 5% · progress 91%
95+
jev nudge 2: unfinished work found (74%), continuing
96+
97+
agent ▸ write smoke-3-blaze.txt ... (nudge 3)
98+
agent ▸ write smoke-4-ember.txt ... (nudge 4)
99+
100+
agent ▸ write smoke-5-ash.txt
101+
all five files are done
102+
┊ stop → Jev: nudge 5% → no nudge, run ends
103+
104+
you ▸ _
105+
```
106+
107+
Tell it "do one step, then wait for my go-ahead" instead and the waiting guard blocks the nudge:
108+
109+
```
110+
agent ▸ Created smoke-1-ignite.txt. Want me to go on?
111+
┊ stop → Jev: nudge 41% · waiting 88%
112+
jev-nudge: turn 2, no nudge (waiting on the user (88%)) ← only with jev-nudge-verbose=true
113+
you ▸ _
114+
```
115+
116+
The `┊ stop → Jev` lines show what happens under the hood. The feed shows only the `jev nudge`
117+
rows. Add `DEBUG=true` to print every decision to stderr.
118+
119+
### Offline
120+
121+
`scripts/fake-jev.mjs` fakes the API with fixed rules. It nudges unless the reply says it's done,
122+
reports waiting when the reply ends in a question, and counts progress when tools ran since the last
123+
nudge. Every request lands in `jev-log.jsonl`.
124+
125+
```bash
126+
node scripts/fake-jev.mjs &
127+
CMD_API_KEY=x cmd --mod . --mod-option jev-nudge-base-url=http://127.0.0.1:4711 --mod-option jev-nudge-verbose=true
128+
```
129+
130+
## Develop
131+
132+
```bash
133+
pnpm install
134+
pnpm test
135+
pnpm typecheck
136+
pnpm lint
137+
```
138+
139+
`src/protocol.ts` builds the state, questions, and decision with no I/O. `src/client.ts` makes the
140+
HTTP call. `src/index.ts` registers the hooks.

‎biome.json‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.5.14/schema.json",
3+
"files": {
4+
"includes": ["src/**", "*.json"]
5+
},
6+
"formatter": {
7+
"enabled": true,
8+
"indentStyle": "tab",
9+
"lineWidth": 80
10+
},
11+
"javascript": {
12+
"formatter": {
13+
"quoteStyle": "single",
14+
"arrowParentheses": "asNeeded",
15+
"bracketSpacing": false,
16+
"trailingCommas": "all"
17+
}
18+
},
19+
"linter": {
20+
"enabled": true,
21+
"preset": "recommended"
22+
}
23+
}

‎package.json‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"name": "cmd-mod-jev-nudge",
3+
"version": "0.1.0",
4+
"description": "Command Code mod: nudges the agent to keep going when it stops with work left, judged by Jev",
5+
"keywords": [
6+
"command-code",
7+
"commandcode",
8+
"cmd",
9+
"mod",
10+
"jev",
11+
"typesafe",
12+
"stop-hook",
13+
"agent"
14+
],
15+
"license": "MIT",
16+
"author": "Ahmad Awais <me@ahmadawais.com>",
17+
"homepage": "https://github.com/CommandCodeAI/cmd-mod-jev-nudge#readme",
18+
"repository": {
19+
"type": "git",
20+
"url": "git+https://github.com/CommandCodeAI/cmd-mod-jev-nudge.git"
21+
},
22+
"bugs": "https://github.com/CommandCodeAI/cmd-mod-jev-nudge/issues",
23+
"type": "module",
24+
"commandcode": {
25+
"mods": [
26+
"./src/index.ts"
27+
]
28+
},
29+
"files": [
30+
"src",
31+
"!src/__tests__",
32+
"README.md"
33+
],
34+
"engines": {
35+
"node": ">=20"
36+
},
37+
"publishConfig": {
38+
"access": "public"
39+
},
40+
"scripts": {
41+
"test": "vitest run",
42+
"typecheck": "tsc --noEmit",
43+
"lint": "biome check .",
44+
"format": "biome format --write .",
45+
"prepublishOnly": "pnpm typecheck && pnpm test"
46+
},
47+
"dependencies": {
48+
"zod": "^4.1.5"
49+
},
50+
"devDependencies": {
51+
"@biomejs/biome": "^2.2.0",
52+
"@types/node": "^22.0.0",
53+
"typescript": "^5.9.2",
54+
"vitest": "^4.1.11"
55+
}
56+
}

0 commit comments

Comments
 (0)