@pedrocivita/tocket 2.5.0 → 2.6.4
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 +233 -18
- package/dist/commands/agents-md.cmd.d.ts +2 -0
- package/dist/commands/agents-md.cmd.js +166 -0
- package/dist/commands/agents-md.cmd.js.map +1 -0
- package/dist/commands/decide.cmd.d.ts +2 -0
- package/dist/commands/decide.cmd.js +70 -0
- package/dist/commands/decide.cmd.js.map +1 -0
- package/dist/commands/doctor.cmd.d.ts +13 -0
- package/dist/commands/doctor.cmd.js +135 -11
- package/dist/commands/doctor.cmd.js.map +1 -1
- package/dist/commands/eject.cmd.d.ts +1 -1
- package/dist/commands/eject.cmd.js +3 -1
- package/dist/commands/eject.cmd.js.map +1 -1
- package/dist/commands/init.cmd.js +67 -13
- package/dist/commands/init.cmd.js.map +1 -1
- package/dist/commands/scaffold.cmd.d.ts +2 -0
- package/dist/commands/scaffold.cmd.js +118 -0
- package/dist/commands/scaffold.cmd.js.map +1 -0
- package/dist/commands/suite.cmd.d.ts +2 -0
- package/dist/commands/suite.cmd.js +387 -0
- package/dist/commands/suite.cmd.js.map +1 -0
- package/dist/commands/validate.cmd.js +1 -0
- package/dist/commands/validate.cmd.js.map +1 -1
- package/dist/commands/work.cmd.d.ts +2 -0
- package/dist/commands/work.cmd.js +48 -0
- package/dist/commands/work.cmd.js.map +1 -0
- package/dist/eval/decide-eval.d.ts +28 -0
- package/dist/eval/decide-eval.js +34 -0
- package/dist/eval/decide-eval.js.map +1 -0
- package/dist/eval/triage-eval.d.ts +46 -0
- package/dist/eval/triage-eval.js +175 -0
- package/dist/eval/triage-eval.js.map +1 -0
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +7 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.js +360 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/templates/memory-bank.d.ts +11 -0
- package/dist/templates/memory-bank.js +456 -329
- package/dist/templates/memory-bank.js.map +1 -1
- package/dist/tests/agents.test.js +73 -1
- package/dist/tests/agents.test.js.map +1 -1
- package/dist/tests/context.test.js +10 -1
- package/dist/tests/context.test.js.map +1 -1
- package/dist/tests/decide.test.d.ts +1 -0
- package/dist/tests/decide.test.js +483 -0
- package/dist/tests/decide.test.js.map +1 -0
- package/dist/tests/doctor.test.js +74 -1
- package/dist/tests/doctor.test.js.map +1 -1
- package/dist/tests/eject.test.js +3 -0
- package/dist/tests/eject.test.js.map +1 -1
- package/dist/tests/git.test.js +17 -0
- package/dist/tests/git.test.js.map +1 -1
- package/dist/tests/helpers.d.ts +6 -0
- package/dist/tests/helpers.js +13 -0
- package/dist/tests/helpers.js.map +1 -0
- package/dist/tests/helpers.test.d.ts +1 -0
- package/dist/tests/helpers.test.js +23 -0
- package/dist/tests/helpers.test.js.map +1 -0
- package/dist/tests/init.test.js +85 -5
- package/dist/tests/init.test.js.map +1 -1
- package/dist/tests/loop.test.d.ts +1 -0
- package/dist/tests/loop.test.js +153 -0
- package/dist/tests/loop.test.js.map +1 -0
- package/dist/tests/memory-bank.test.js +53 -1
- package/dist/tests/memory-bank.test.js.map +1 -1
- package/dist/tests/suite.test.d.ts +1 -0
- package/dist/tests/suite.test.js +199 -0
- package/dist/tests/suite.test.js.map +1 -0
- package/dist/tests/triage.test.d.ts +1 -0
- package/dist/tests/triage.test.js +152 -0
- package/dist/tests/triage.test.js.map +1 -0
- package/dist/tests/work.test.d.ts +1 -0
- package/dist/tests/work.test.js +276 -0
- package/dist/tests/work.test.js.map +1 -0
- package/dist/utils/agents.d.ts +25 -0
- package/dist/utils/agents.js +92 -0
- package/dist/utils/agents.js.map +1 -1
- package/dist/utils/appmaps.d.ts +65 -0
- package/dist/utils/appmaps.js +280 -0
- package/dist/utils/appmaps.js.map +1 -0
- package/dist/utils/context.d.ts +2 -0
- package/dist/utils/context.js +21 -0
- package/dist/utils/context.js.map +1 -1
- package/dist/utils/decide.d.ts +178 -0
- package/dist/utils/decide.js +614 -0
- package/dist/utils/decide.js.map +1 -0
- package/dist/utils/git.js +8 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/jev.d.ts +83 -0
- package/dist/utils/jev.js +190 -0
- package/dist/utils/jev.js.map +1 -0
- package/dist/utils/triage.d.ts +87 -0
- package/dist/utils/triage.js +241 -0
- package/dist/utils/triage.js.map +1 -0
- package/dist/utils/work.d.ts +72 -0
- package/dist/utils/work.js +225 -0
- package/dist/utils/work.js.map +1 -0
- package/package.json +53 -50
package/README.md
CHANGED
|
@@ -5,32 +5,86 @@
|
|
|
5
5
|
|
|
6
6
|
# Tocket
|
|
7
7
|
|
|
8
|
-
**
|
|
8
|
+
Tocket is the **project notebook**: folders/files many AI agents read and write together. It is not a chat and does not do the work alone.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Jev (and similar) only **picks among options** and **saves that choice in the notebook**. Cursor/Claude/GrokBot/CI still do the work.
|
|
11
|
+
|
|
12
|
+
**Agents work · Tocket remembers · Jev only chooses the next step.**
|
|
13
|
+
|
|
14
|
+
Tocket é o caderno do projeto: pastas e arquivos que vários agentes leem e escrevem juntos. Não é um chat e não faz o trabalho sozinho. O Jev só escolhe entre opções e grava essa escolha no caderno.
|
|
15
|
+
|
|
16
|
+
## Harness your context
|
|
17
|
+
|
|
18
|
+
Tocket is a file-first harness, not a LangChain runtime. The AutoMode *pattern* (judge before irreversible tools) lives in `.context/decisions/` JSON, not in middleware. Jev is the judge, not the writer. Before bash, deploy, or browser, `tocket decide` records `tool_gate: allow|block|ask`; `tocket work --apply` honors that gate. No new runtime deps.
|
|
19
|
+
|
|
20
|
+
The Context Engineering Framework for Multi-Agent Workspaces. Agents forget everything between sessions. Tocket keeps shared context in files any agent can read: no vendor lock-in, no special integrations.
|
|
11
21
|
|
|
12
22
|
<p align="center">
|
|
13
23
|
<img src="docs/assets/tocket-dashboard.png" alt="Tocket CLI Dashboard" width="700" />
|
|
14
24
|
</p>
|
|
15
25
|
|
|
26
|
+
## What's new in 2.6.4
|
|
27
|
+
|
|
28
|
+
- Windows follow-up: suite/triage/doctor/init print posix `toRepoRelative` paths; decide tests use `includesPath` (separators); Cursor `CURSOR_*` env detection is case-insensitive and init tests isolate `HOME` so `.cursorrules` is written.
|
|
29
|
+
|
|
30
|
+
## What's new in 2.6.3
|
|
31
|
+
|
|
32
|
+
- Windows test/path fixes: skill/template equality ignores CRLF vs LF; CLI `from=` and other `toRepoRelative` display paths use posix `/` on every OS. 2.6.2 never published successfully.
|
|
33
|
+
|
|
34
|
+
## What's new in 2.6.2
|
|
35
|
+
|
|
36
|
+
- Tool-risk gate: `tocket decide --choice tool_gate:allow,block,ask` records allow|block|ask. `tocket work --apply` refuses `block`/`ask` (exit 2) unless `--force`. Shadow apply still needs `--force`.
|
|
37
|
+
- Installer docs + auto-config: `AGENTS.md`, fuller README how-it-works, skill rules, `tocket init` writes `AGENTS.md` and the matching agent file (detect or ask once).
|
|
38
|
+
|
|
39
|
+
## What's new in 2.6.1
|
|
40
|
+
|
|
41
|
+
- `tocket work`: first-party reference worker. Reads a Choice from `.context/decisions/` and prints a plan (default) or `--apply` a notebook receipt. Never calls Jev. Shadow / log-only apply requires `--force`.
|
|
42
|
+
|
|
43
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
|
44
|
+
|
|
45
|
+
## What's new in 2.6.0
|
|
46
|
+
|
|
47
|
+
- `tocket decide`: cheap typed Choice into `.context/decisions/`
|
|
48
|
+
- Light `tocket doctor`: notebook checks (`.context/`, skill, key yes/no, last decision)
|
|
49
|
+
- Official skill: `npx skills add pedrocivita/tocket --skill tocket`
|
|
50
|
+
|
|
51
|
+
## What you get
|
|
52
|
+
|
|
53
|
+
| Piece | Role |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| `tocket decide` | Writes the next move as JSON under `.context/decisions/`. Does not run workers. |
|
|
56
|
+
| `tocket work` | Reads that Choice and plans (default) or `--apply` a notebook receipt. Honors `tool_gate`. Does not call Jev. |
|
|
57
|
+
| `tocket doctor` | Green/yellow/red checks for the notebook, skill file, and `TYPESAFE_API_KEY` yes/no. |
|
|
58
|
+
| `tocket suite loop` | Copies AppMap + last-run into `.context/appmaps/` and triages. Suite-specific. |
|
|
59
|
+
| Official skill | One-shot install. Phrase: before expensive tools, `tocket decide --dry-run` or read `.context/decisions/`. |
|
|
60
|
+
|
|
61
|
+
## What Tocket is not
|
|
62
|
+
|
|
63
|
+
- **Not a chatbot.** Context lives in files, not in a conversation.
|
|
64
|
+
- **Not a computer-use runtime.** It does not drive a browser or click the OS.
|
|
65
|
+
- **Not codegen.** It does not write application code. Workers (Cursor, Claude, GrokBot, CI) do.
|
|
66
|
+
|
|
16
67
|
## The idea in 30 seconds
|
|
17
68
|
|
|
18
69
|
Tocket is a file convention. It adds a `.context/` directory to your repo with markdown files that describe your project's current state, architecture, and progress. Any AI agent that can read files — Claude, Gemini, GPT, Cursor, Copilot — can pick up where the last session left off.
|
|
19
70
|
|
|
20
71
|
```
|
|
21
72
|
your-project/
|
|
73
|
+
AGENTS.md # Start here (any agent: Cursor, Claude, Gemini, Copilot, …)
|
|
22
74
|
.context/
|
|
23
75
|
activeContext.md # What's happening right now
|
|
24
76
|
systemPatterns.md # How the codebase is organized
|
|
25
77
|
techContext.md # Stack and build tools
|
|
26
78
|
productContext.md # What the product is and why
|
|
27
79
|
progress.md # What's done, what's next
|
|
80
|
+
decisions/ # decide JSON + work receipts
|
|
28
81
|
TOCKET.md # Protocol rules (agent-agnostic)
|
|
29
|
-
CLAUDE.md
|
|
30
|
-
GEMINI.md # Architect instructions
|
|
82
|
+
CLAUDE.md / .cursorrules / … # Executor file (init detects or asks once)
|
|
83
|
+
GEMINI.md # Architect instructions
|
|
84
|
+
.agents/skills/tocket/SKILL.md
|
|
31
85
|
```
|
|
32
86
|
|
|
33
|
-
All files are plain markdown, committed to git, and readable by any tool.
|
|
87
|
+
All files are plain markdown, committed to git, and readable by any tool. `npx @pedrocivita/tocket init` writes them so the preferred agent is wired without copy-paste.
|
|
34
88
|
|
|
35
89
|
## You don't need the CLI
|
|
36
90
|
|
|
@@ -42,23 +96,33 @@ The protocol is just files. You can adopt it manually:
|
|
|
42
96
|
|
|
43
97
|
The CLI automates the scaffolding, provides smart defaults, and adds quality-of-life tooling around the protocol.
|
|
44
98
|
|
|
45
|
-
## Quick Start
|
|
99
|
+
## Quick Start (5 minutes)
|
|
46
100
|
|
|
47
101
|
```bash
|
|
48
|
-
#
|
|
102
|
+
# 1. Self-configuring notebook (detects or asks once for Cursor / Claude / …)
|
|
49
103
|
npx @pedrocivita/tocket init
|
|
104
|
+
# npx @pedrocivita/tocket init --executor Cursor --architect Gemini --force
|
|
105
|
+
# or: npx @pedrocivita/tocket init --minimal
|
|
106
|
+
|
|
107
|
+
# 2. Conventions check (notebook, AGENTS.md, skill, key yes/no)
|
|
108
|
+
tocket doctor
|
|
50
109
|
|
|
51
|
-
#
|
|
52
|
-
|
|
110
|
+
# 3. Next move (no API key: stub). Jev is the judge, not the writer.
|
|
111
|
+
tocket decide --dry-run --state '{"goal":"docs"}' --choice next:research,write,review
|
|
53
112
|
|
|
54
|
-
#
|
|
55
|
-
|
|
113
|
+
# 4. Agents read the choice (do not re-ask Jev if this file exists)
|
|
114
|
+
# .context/decisions/<research|write|review>/*.json
|
|
56
115
|
|
|
57
|
-
#
|
|
58
|
-
|
|
116
|
+
# 5. Staging: dry-run plan, then apply a notebook receipt
|
|
117
|
+
tocket work --from .context/decisions/review/<file>.json
|
|
118
|
+
tocket work --from .context/decisions/review/<file>.json --apply
|
|
59
119
|
```
|
|
60
120
|
|
|
61
|
-
|
|
121
|
+
Optional one-shot skill: `npx skills add pedrocivita/tocket --skill tocket`.
|
|
122
|
+
|
|
123
|
+
Optional live Jev: `export TYPESAFE_API_KEY=…` (never print the value). Without it, decide stays on the stub.
|
|
124
|
+
|
|
125
|
+
Workers execute the chosen move. Tocket only writes the notebook. Every AI session starts at `AGENTS.md`, then `.context/activeContext.md`.
|
|
62
126
|
|
|
63
127
|
### Safe testing — use a branch
|
|
64
128
|
|
|
@@ -85,14 +149,23 @@ See the [Developer Guide](docs/DEVELOPERS_GUIDE.md) for detailed safe-testing wo
|
|
|
85
149
|
| --- | --- |
|
|
86
150
|
| `tocket` | Interactive dashboard with guided menu |
|
|
87
151
|
| `tocket init` | Scaffold `.context/`, `TOCKET.md`, and agent configs (auto-detects stack + agents) |
|
|
88
|
-
| `tocket generate` | Build structured payload XML (auto-fills scope from git) |
|
|
152
|
+
| `tocket generate` | Build structured payload XML (auto-fills scope from git, saves to `.tocket/`) |
|
|
153
|
+
| `tocket diff` | Compare payload targets against actual git changes (verify executor compliance) |
|
|
89
154
|
| `tocket sync` | Append session summary + git log to `.context/progress.md` |
|
|
155
|
+
| `tocket handoff` | Generate clipboard-ready context summary for a new agent conversation |
|
|
90
156
|
| `tocket validate` | Check if the workspace has a valid Memory Bank |
|
|
91
157
|
| `tocket focus` | Update the Current Focus in `activeContext.md` |
|
|
92
158
|
| `tocket status` | Quick overview: workspace health, branch, focus, agents |
|
|
93
|
-
| `tocket doctor` |
|
|
159
|
+
| `tocket doctor` | Light notebook checks (`.context/`, decisions, key yes/no, last decision) plus diagnostics |
|
|
94
160
|
| `tocket lint` | Audit `.context/` content quality and suggest improvements |
|
|
95
161
|
| `tocket config` | Manage global settings: agent roles, author, priority (`~/.tocketrc.json`) |
|
|
162
|
+
| `tocket suite status` | Print last AppMap run from `.context/appmaps/last-run.json` (exit 1 if failed, 2 if missing) |
|
|
163
|
+
| `tocket suite sync --from <path.json>` | Validate and copy a last-run.json into `.context/appmaps/`, regenerate `last-run.md` |
|
|
164
|
+
| `tocket suite init` | Scaffold empty `.context/appmaps/` index templates |
|
|
165
|
+
| `tocket suite triage` | Triage failed goals (Jev Choice, or heuristic stub without `TYPESAFE_API_KEY`) |
|
|
166
|
+
| `tocket suite loop` | Copy mapper AppMap + optional last-run into `.context/appmaps/` and triage |
|
|
167
|
+
| `tocket decide` | State + Choice handoff into `.context/decisions/` (Codila-style queues; does not run workers) |
|
|
168
|
+
| `tocket work` | Read a decision and print a plan (default) or `--apply` a notebook receipt. Never calls Jev. |
|
|
96
169
|
| `tocket eject` | Remove all Tocket files (with confirmation) |
|
|
97
170
|
|
|
98
171
|
### CI-friendly flags
|
|
@@ -109,10 +182,133 @@ tocket sync --summary "Fixed auth bug and added tests"
|
|
|
109
182
|
# Generate to stdout or file instead of clipboard
|
|
110
183
|
tocket generate --to stdout
|
|
111
184
|
tocket generate --to payload.xml
|
|
185
|
+
|
|
186
|
+
# Verify executor followed the payload
|
|
187
|
+
tocket diff
|
|
188
|
+
tocket diff --json
|
|
189
|
+
|
|
190
|
+
# Handoff context to a new session
|
|
191
|
+
tocket handoff --to stdout
|
|
192
|
+
|
|
193
|
+
# AppMap last-run (file-first; does not execute maps)
|
|
194
|
+
tocket suite status
|
|
195
|
+
tocket suite sync --from path/to/last-run.json
|
|
196
|
+
tocket suite init
|
|
197
|
+
tocket suite triage --from path/to/last-run.json --dry-run
|
|
198
|
+
tocket suite loop --app tempestivita --map out/tempestivita.appmap.json --last-run last-run.json --dry-run
|
|
199
|
+
|
|
200
|
+
# Generic decision (Choice + optional Noul/Score). File handoff only.
|
|
201
|
+
tocket decide --state '{"goal":"docs"}' --choice next:research,write,review --dry-run
|
|
202
|
+
tocket decide --from path/to/state.json --noul needs_human_review --score relevance --shadow
|
|
203
|
+
tocket decide --from path/to/state.json --choice next:research,write,review --fork action --confidence-threshold 0.85
|
|
204
|
+
|
|
205
|
+
# Tool-risk gate (Jev judges; workers execute; Tocket does not run tools)
|
|
206
|
+
tocket decide --from path/to/state.json --choice tool_gate:allow,block,ask --shadow
|
|
207
|
+
tocket work --from path/to/decision.json
|
|
208
|
+
tocket work --from path/to/decision.json --apply
|
|
209
|
+
|
|
210
|
+
# Reference worker (no Jev). Default is plan/dry-run.
|
|
211
|
+
tocket work --from path/to/decision.json
|
|
212
|
+
tocket work --apply
|
|
213
|
+
tocket work --from path/to/decision.json --apply
|
|
214
|
+
tocket work --from path/to/shadow.json --apply --force
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Tempestivita loop (Oficina)
|
|
218
|
+
|
|
219
|
+
Three steps. Mapper is a sibling tool ([pedrocivita/appmap-mapper](https://github.com/pedrocivita/appmap-mapper)); Tocket does not vendor it.
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
# 1. Mapper — emit out/tempestivita.appmap.json (and optional smoke)
|
|
223
|
+
cd ../appmap-mapper
|
|
224
|
+
npx tsx src/cli.ts all --url https://tempestivita.civita.dev --smoke
|
|
225
|
+
|
|
226
|
+
# 2. Close the Memory Bank (map + last-run + triage stay under .context/)
|
|
227
|
+
cd ../tocket
|
|
228
|
+
tocket suite loop --app tempestivita \
|
|
229
|
+
--mapper-out ../appmap-mapper/out \
|
|
230
|
+
--last-run path/to/last-run.json \
|
|
231
|
+
--dry-run
|
|
232
|
+
|
|
233
|
+
# 3. Read what loop wrote
|
|
234
|
+
tocket suite status
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
`--mapper-out` discovers `*.appmap.json` (prefers `<app>.appmap.json`). `--dry-run` uses the heuristic stub when `TYPESAFE_API_KEY` is missing. `--no-triage` copies files only.
|
|
238
|
+
|
|
239
|
+
### `tocket decide` (Codila-style file handoff)
|
|
240
|
+
|
|
241
|
+
`tocket decide` is Tocket's file-handoff cousin of [Codila's `chief.py` queues](https://x.com/0xCodila/status/2100984487802708306) (DataChaz 10-step summary). LLMs create, agents act, Jev decides the next move. The CLI writes a JSON that agents or other CLIs consume later.
|
|
242
|
+
|
|
112
243
|
```
|
|
244
|
+
State → Questions (batched) → Action (this file) → Verify (the consumer)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
- Payload includes `choice`, `confidence`, `destination`, `state`, `fork`, and `executes: false`.
|
|
248
|
+
- Primitives: Choice + Noul now; `--score name` or `--score name:min,max` is optional. All flags batch into one System One request.
|
|
249
|
+
- Research/write route only when confidence >= 0.85 (override with `--confidence-threshold`). Below that, `destination` is `review` and `gated` is true.
|
|
250
|
+
- `--fork agent|model|tool|action|human` (default `action`). `--fork human` always reviews. `--fork model` is the existing cheap model-router hook (no extra UX in this release).
|
|
251
|
+
- `--choice tool_gate:allow,block,ask` (or `action_gate`) records a tool-risk gate. `tocket work --apply` refuses `block` and `ask` unless `--force`.
|
|
252
|
+
- `--dry-run` or no `TYPESAFE_API_KEY`: deterministic stub. With a key: live Jev. `--shadow`: live call, `semantics: log-only`.
|
|
253
|
+
- `tocket suite triage` is suite-specific (last-run failures). Suite loop still calls triage, not decide.
|
|
254
|
+
|
|
255
|
+
#### Boundaries (do / do not)
|
|
256
|
+
|
|
257
|
+
1. **Jev decides the next move.** LLMs create. Agents act. This command is the decision node.
|
|
258
|
+
2. **Primitives are Choice, Score, Noul.** Start with Choice + Noul. Score is optional. Do not send prose generation to Jev.
|
|
259
|
+
3. **Swap the decision node.** Do not rebuild the agent graph around Jev.
|
|
260
|
+
4. **Shared state + parallel questions + risk threshold + file queue.** Writes stay under `.context/decisions/<research|write|review>/`.
|
|
261
|
+
5. **Batch questions in one request.** Repeat `--choice` / `--noul` / `--score`; they share one System One call.
|
|
262
|
+
6. **Bounded forks only:** agent, model, tool, action, or human escalate. Not an open-ended graph.
|
|
263
|
+
7. **Whole-loop benchmark is out of scope** for this command (do that later, separately).
|
|
264
|
+
8. **Rank wide / read narrow.** Choice may list many options; the handoff stores the single `narrow` route (not every option).
|
|
265
|
+
9. **Reuse the loop:** State → Questions → Action (file) → Verify (consumer). `tocket work` is the reference consumer.
|
|
266
|
+
10. **Keep Jev out of math, writing, and irreversible execution.** This CLI writes a file. It does not compute, draft, publish, or apply.
|
|
267
|
+
|
|
268
|
+
`executes` is always `false`. Workers (or humans) read the JSON. Tocket does not run them.
|
|
269
|
+
|
|
270
|
+
### `tocket work` (reference worker)
|
|
271
|
+
|
|
272
|
+
`tocket decide` writes. `tocket work` is the first-party consumer: it reads a Choice and acts on the notebook only. It does not call Jev, open a browser, or edit application code.
|
|
273
|
+
|
|
274
|
+
Default is a dry-run plan (choice, destination, confidence, gated, tool_gate). `--apply` writes `<id>.applied.json` next to the decision and a `worker applied: next=…` line into `.context/progress.md`. Shadow / `semantics: log-only` decisions refuse `--apply` with exit 2 unless `--force` (receipt then has `applied_from_shadow: true`). A `tool_gate` of `block` or `ask` also refuses `--apply` (exit 2; `ask` tells you to escalate to a human) unless `--force`. Missing or invalid JSON exits 1.
|
|
275
|
+
|
|
276
|
+
A later `--backend laya` (local Apple Silicon) is not implemented. Today: stub, or live Jev with `TYPESAFE_API_KEY`.
|
|
277
|
+
|
|
278
|
+
What lands in `.context/appmaps/`:
|
|
279
|
+
|
|
280
|
+
| File | Source |
|
|
281
|
+
| --- | --- |
|
|
282
|
+
| `tempestivita.appmap.json` | Mapper (or `--map`) copy |
|
|
283
|
+
| `last-run.json` / `last-run.md` | `--last-run` via the same v0 schema as `suite sync` |
|
|
284
|
+
| `tempestivita.triage.json` | Failed + low-confidence goals (unless `--no-triage`) |
|
|
285
|
+
|
|
286
|
+
Thin wrapper: `scripts/tempestivita-loop.sh` (sets `--app tempestivita` and `--mapper-out`).
|
|
113
287
|
|
|
114
288
|
## How it works
|
|
115
289
|
|
|
290
|
+
Installers (`npm i` / `npx`) get ready context in the package. Any agent that can read files is productive after `init` + `doctor` + the skill phrase.
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
init (detect agent, write AGENTS.md + instruction files)
|
|
294
|
+
→ doctor (notebook green/yellow/red; TYPESAFE_API_KEY yes/no)
|
|
295
|
+
→ decide (Jev or stub writes .context/decisions/)
|
|
296
|
+
→ work dry-run plan (never calls Jev)
|
|
297
|
+
→ work --apply notebook receipt if tool_gate allows
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
| Piece | Role |
|
|
301
|
+
| --- | --- |
|
|
302
|
+
| `.context/` | Shared notebook. Read before acting. Update after work. |
|
|
303
|
+
| `AGENTS.md` | Single source agents read first. Decide vs work, never re-ask Jev, honor `tool_gate`. |
|
|
304
|
+
| `tocket decide` | Judge. Writes allow/block/ask or the next move. Does not run tools. |
|
|
305
|
+
| `tocket work` | Staging: plan by default, `--apply` stamps a receipt. Honors `tool_gate`. |
|
|
306
|
+
| `tool_gate` | `allow` proceeds. `block` stops. `ask` escalates to a human. `--force` overrides. |
|
|
307
|
+
| `--fork model` | Cheap model-router hook (bounded forks: agent, model, tool, action, human). |
|
|
308
|
+
| Shadow-first | `--dry-run` / `--shadow` is log-only. Shadow apply still needs `--force`. |
|
|
309
|
+
| `tocket doctor` | Checks `.context/`, `AGENTS.md`, skill, last decision, key yes/no. |
|
|
310
|
+
| Skill | `npx skills add pedrocivita/tocket --skill tocket`. Same rules as `AGENTS.md`. |
|
|
311
|
+
|
|
116
312
|
### Memory Bank
|
|
117
313
|
|
|
118
314
|
The `.context/` directory is the project's shared memory. Agents read it before acting and update it after completing work. Context lives in files, not in chat history.
|
|
@@ -124,6 +320,9 @@ The `.context/` directory is the project's shared memory. Agents read it before
|
|
|
124
320
|
| `techContext.md` | Stack, build tools, critical rules | When stack changes |
|
|
125
321
|
| `productContext.md` | What the product is and why | Rarely |
|
|
126
322
|
| `progress.md` | Milestones and completed work | Per milestone |
|
|
323
|
+
| `appmaps/` | Optional AppMap index + map copy + last-run + triage | `tocket suite loop` / `sync` |
|
|
324
|
+
| `decisions/` | Choice/Noul handoff queues (`research/`, `write/`, `review/`) plus `*.applied.json` receipts | `tocket decide` / `tocket work` |
|
|
325
|
+
| `AGENTS.md` (repo root) | Agent-first rules: decide vs work, `tool_gate`, do not re-ask Jev | `tocket init` / `tocket agents-md` |
|
|
127
326
|
|
|
128
327
|
### Triangulation
|
|
129
328
|
|
|
@@ -139,10 +338,25 @@ Architect (any planning AI) Executor (any coding AI)
|
|
|
139
338
|
| | 4. Reads .context/ + payload
|
|
140
339
|
| | 5. Implements tasks
|
|
141
340
|
| | 6. Updates .context/
|
|
142
|
-
|<--------
|
|
341
|
+
|<-------- tocket diff report ------|
|
|
143
342
|
```
|
|
144
343
|
|
|
145
|
-
The Architect doesn't write code. The Executor doesn't make architecture decisions. The payload XML is the contract between them. For simple tasks, a single agent can fill both roles.
|
|
344
|
+
The Architect doesn't write code. The Executor doesn't make architecture decisions. The payload XML is the contract between them. After execution, `tocket diff` verifies compliance — did the Executor touch the right files? Are done criteria met? For simple tasks, a single agent can fill both roles.
|
|
345
|
+
|
|
346
|
+
### Closing the loop
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
# After the Executor finishes work:
|
|
350
|
+
tocket diff # compare payload targets vs actual git changes
|
|
351
|
+
tocket diff --json # machine-readable output
|
|
352
|
+
tocket diff --since HEAD~3 # diff against a specific ref
|
|
353
|
+
|
|
354
|
+
# Starting a new session (next day, new chat):
|
|
355
|
+
tocket handoff # copies context summary to clipboard
|
|
356
|
+
tocket handoff --to stdout # print instead
|
|
357
|
+
tocket handoff --commits 10 # include more history
|
|
358
|
+
tocket handoff --since 1d # files modified in last day
|
|
359
|
+
```
|
|
146
360
|
|
|
147
361
|
## Who is this for?
|
|
148
362
|
|
|
@@ -204,6 +418,7 @@ Don't see your agent? It still works — unknown agents get generic files, and y
|
|
|
204
418
|
| [Getting Started](docs/GETTING_STARTED.md) | Set up your first Tocket workspace in 5 minutes |
|
|
205
419
|
| [Developer Guide](docs/DEVELOPERS_GUIDE.md) | How to run the Tocket protocol safely in any project |
|
|
206
420
|
| [Tocket Rules](docs/TOCKET_RULES.md) | Complete reference for all protocol rules |
|
|
421
|
+
| [AGENTS.md](AGENTS.md) | What agents read first (decide vs work, tool_gate) |
|
|
207
422
|
| [Protocol Spec](TOCKET.md) | The agent-agnostic protocol specification |
|
|
208
423
|
| [Walkthrough](examples/walkthrough.md) | End-to-end payload exchange example |
|
|
209
424
|
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { existsSync, readFileSync, watch } from "node:fs";
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { success, error as themeError, heading, info, dim } from "../utils/theme.js";
|
|
5
|
+
import { agentsProtocolSection } from "../templates/memory-bank.js";
|
|
6
|
+
function readContextFiles(cwd) {
|
|
7
|
+
const contextDir = join(cwd, ".context");
|
|
8
|
+
const activeContext = existsSync(join(contextDir, "activeContext.md"))
|
|
9
|
+
? readFileSync(join(contextDir, "activeContext.md"), "utf-8")
|
|
10
|
+
: "";
|
|
11
|
+
const systemPatterns = existsSync(join(contextDir, "systemPatterns.md"))
|
|
12
|
+
? readFileSync(join(contextDir, "systemPatterns.md"), "utf-8")
|
|
13
|
+
: "";
|
|
14
|
+
const techContext = existsSync(join(contextDir, "techContext.md"))
|
|
15
|
+
? readFileSync(join(contextDir, "techContext.md"), "utf-8")
|
|
16
|
+
: "";
|
|
17
|
+
const productContext = existsSync(join(contextDir, "productContext.md"))
|
|
18
|
+
? readFileSync(join(contextDir, "productContext.md"), "utf-8")
|
|
19
|
+
: "";
|
|
20
|
+
return { activeContext, systemPatterns, techContext, productContext };
|
|
21
|
+
}
|
|
22
|
+
function extractSection(content, sectionName) {
|
|
23
|
+
const lines = content.split("\n");
|
|
24
|
+
const startIndex = lines.findIndex(line => line.includes(`## ${sectionName}`));
|
|
25
|
+
if (startIndex === -1)
|
|
26
|
+
return "";
|
|
27
|
+
let endIndex = lines.length;
|
|
28
|
+
for (let i = startIndex + 1; i < lines.length; i++) {
|
|
29
|
+
if (lines[i].startsWith("## ")) {
|
|
30
|
+
endIndex = i;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return lines.slice(startIndex + 1, endIndex).join("\n").trim();
|
|
35
|
+
}
|
|
36
|
+
function generateAgentsMdContent(projectName, description, contextFiles, executorName = "Claude Code", architectName = "Gemini") {
|
|
37
|
+
const currentFocus = extractSection(contextFiles.activeContext, "Current Focus");
|
|
38
|
+
const techStack = extractSection(contextFiles.techContext, "Stack");
|
|
39
|
+
const conventions = extractSection(contextFiles.systemPatterns, "Conventions");
|
|
40
|
+
const keyDecisions = extractSection(contextFiles.systemPatterns, "Key Decisions");
|
|
41
|
+
const architectureSection = extractSection(contextFiles.systemPatterns, "Architecture Patterns");
|
|
42
|
+
const content = `# AGENTS.md — ${projectName}
|
|
43
|
+
|
|
44
|
+
> Written by \`tocket init\` / \`tocket agents-md\`. Refresh project facts here. Keep the decide/work rules.
|
|
45
|
+
|
|
46
|
+
## About this project
|
|
47
|
+
|
|
48
|
+
${description || "_No description provided._"}
|
|
49
|
+
|
|
50
|
+
## Instructions for AI agents
|
|
51
|
+
|
|
52
|
+
1. Read this file first, then \`.context/activeContext.md\`
|
|
53
|
+
2. Read \`.context/systemPatterns.md\` for architecture decisions and conventions
|
|
54
|
+
3. Update \`.context/activeContext.md\` after completing significant work
|
|
55
|
+
4. Follow the full protocol in \`TOCKET.md\`
|
|
56
|
+
|
|
57
|
+
${agentsProtocolSection()}
|
|
58
|
+
## Current Focus
|
|
59
|
+
|
|
60
|
+
${currentFocus || "_Generated from .context/activeContext.md. Run \`tocket agents-md\` to update._"}
|
|
61
|
+
|
|
62
|
+
## Tech Stack
|
|
63
|
+
|
|
64
|
+
${techStack || "_Generated from .context/techContext.md. Run \`tocket agents-md\` to update._"}
|
|
65
|
+
|
|
66
|
+
## Architecture & Conventions
|
|
67
|
+
|
|
68
|
+
${architectureSection ? `### Architecture Patterns\n\n${architectureSection}\n` : ""}
|
|
69
|
+
${conventions ? `### Conventions\n\n${conventions}\n` : ""}
|
|
70
|
+
${keyDecisions ? `### Key Decisions\n\n${keyDecisions}` : ""}
|
|
71
|
+
|
|
72
|
+
## Key Rules
|
|
73
|
+
|
|
74
|
+
- Write all code, comments, and commits in \`en-US\`
|
|
75
|
+
- Do not improvise architecture — follow documented decisions
|
|
76
|
+
- Context belongs in \`.context/\`, not in code comments or chat
|
|
77
|
+
- Triangulation: ${architectName} (Architect) + ${executorName} (Executor)
|
|
78
|
+
`;
|
|
79
|
+
return content;
|
|
80
|
+
}
|
|
81
|
+
async function generateAndWrite(cwd, agentsMdPath, verbose = true) {
|
|
82
|
+
const contextDir = join(cwd, ".context");
|
|
83
|
+
const contextFiles = readContextFiles(cwd);
|
|
84
|
+
let projectName = "Project";
|
|
85
|
+
let description = "";
|
|
86
|
+
const productContextFile = join(contextDir, "productContext.md");
|
|
87
|
+
if (existsSync(productContextFile)) {
|
|
88
|
+
const productContent = readFileSync(productContextFile, "utf-8");
|
|
89
|
+
const nameMatch = productContent.match(/## What is (.+)\?/);
|
|
90
|
+
if (nameMatch)
|
|
91
|
+
projectName = nameMatch[1];
|
|
92
|
+
const descMatch = productContent.match(/## What is .+\?\n\n(.+?)(?:\n\n##|$)/s);
|
|
93
|
+
if (descMatch)
|
|
94
|
+
description = descMatch[1].trim();
|
|
95
|
+
}
|
|
96
|
+
const activeContextFile = join(contextDir, "activeContext.md");
|
|
97
|
+
if (existsSync(activeContextFile)) {
|
|
98
|
+
const activeContent = readFileSync(activeContextFile, "utf-8");
|
|
99
|
+
const nameMatch = activeContent.match(/# Active Context - (.+)/);
|
|
100
|
+
if (nameMatch)
|
|
101
|
+
projectName = nameMatch[1];
|
|
102
|
+
}
|
|
103
|
+
const systemPatternsFile = join(contextDir, "systemPatterns.md");
|
|
104
|
+
let executorName = "Claude Code";
|
|
105
|
+
let architectName = "Gemini";
|
|
106
|
+
if (existsSync(systemPatternsFile)) {
|
|
107
|
+
const systemContent = readFileSync(systemPatternsFile, "utf-8");
|
|
108
|
+
const triangMatch = systemContent.match(/- Triangulation: (.+?) \(Architect\) \+ (.+?) \(Executor\)/);
|
|
109
|
+
if (triangMatch) {
|
|
110
|
+
architectName = triangMatch[1];
|
|
111
|
+
executorName = triangMatch[2];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const generatedContent = generateAgentsMdContent(projectName, description, contextFiles, executorName, architectName);
|
|
115
|
+
await writeFile(agentsMdPath, generatedContent, "utf-8");
|
|
116
|
+
if (verbose) {
|
|
117
|
+
console.log(heading("\n AGENTS.md generated\n"));
|
|
118
|
+
console.log(info(`Location: ${agentsMdPath}`));
|
|
119
|
+
console.log(info(`Size: ${generatedContent.length} bytes`));
|
|
120
|
+
console.log(success(`AGENTS.md is ready for cross-tool compatibility!\n`));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
export function registerAgentsMdCommand(program) {
|
|
124
|
+
program
|
|
125
|
+
.command("agents-md")
|
|
126
|
+
.description("Generate or regenerate AGENTS.md from .context/")
|
|
127
|
+
.option("--watch", "Watch for changes in .context/ and regenerate")
|
|
128
|
+
.action(async (options) => {
|
|
129
|
+
const cwd = process.cwd();
|
|
130
|
+
const contextDir = join(cwd, ".context");
|
|
131
|
+
const agentsMdPath = join(cwd, "AGENTS.md");
|
|
132
|
+
if (!existsSync(contextDir)) {
|
|
133
|
+
console.error(themeError("Memory Bank not found. Run 'tocket init' first."));
|
|
134
|
+
process.exitCode = 1;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
// Initial generation
|
|
139
|
+
await generateAndWrite(cwd, agentsMdPath, !options.watch);
|
|
140
|
+
if (options.watch) {
|
|
141
|
+
console.log(info("Watching .context/ for changes... (Ctrl+C to stop)"));
|
|
142
|
+
const watcher = watch(contextDir, { recursive: false }, (eventType, filename) => {
|
|
143
|
+
if (filename?.endsWith(".md")) {
|
|
144
|
+
console.log(dim(` detected change in ${filename}`));
|
|
145
|
+
generateAndWrite(cwd, agentsMdPath, false).catch((err) => {
|
|
146
|
+
console.error(themeError(`Failed to regenerate: ${err instanceof Error ? err.message : String(err)}`));
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
// Graceful shutdown on SIGINT
|
|
151
|
+
process.on("SIGINT", () => {
|
|
152
|
+
watcher.close();
|
|
153
|
+
process.exit(0);
|
|
154
|
+
});
|
|
155
|
+
// Keep process alive
|
|
156
|
+
await new Promise(() => { });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
161
|
+
console.error(themeError(`Failed to generate AGENTS.md: ${message}`));
|
|
162
|
+
process.exitCode = 1;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=agents-md.cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.cmd.js","sourceRoot":"","sources":["../../src/commands/agents-md.cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from "node:path";
|
|
2
|
+
import { DecideError, formatDecideSummary, parseConfidenceThreshold, runDecide, toRepoRelative, } from "../utils/decide.js";
|
|
3
|
+
import { error as themeError, success } from "../utils/theme.js";
|
|
4
|
+
import { TOCKET_AGENT_PHRASE, TOCKET_SKILLS_ADD } from "../templates/memory-bank.js";
|
|
5
|
+
function collect(value, previous) {
|
|
6
|
+
return previous.concat(value);
|
|
7
|
+
}
|
|
8
|
+
function resolveFromPath(cwd, from) {
|
|
9
|
+
return isAbsolute(from) ? from : resolve(cwd, from);
|
|
10
|
+
}
|
|
11
|
+
export function registerDecideCommand(program) {
|
|
12
|
+
program
|
|
13
|
+
.command("decide")
|
|
14
|
+
.description("Cheap typed Choice into .context/decisions/; workers execute, Tocket does not")
|
|
15
|
+
.addHelpText("after", `
|
|
16
|
+
Tocket is the shared project notebook (.context/). decide writes the next move.
|
|
17
|
+
Workers (Cursor, Claude, GrokBot, CI) execute. Tocket does not.
|
|
18
|
+
|
|
19
|
+
5-minute setup:
|
|
20
|
+
1. npx @pedrocivita/tocket init
|
|
21
|
+
2. ${TOCKET_SKILLS_ADD}
|
|
22
|
+
3. tocket doctor
|
|
23
|
+
4. tocket decide --dry-run --state '{"goal":"docs"}' --choice next:research,write,review
|
|
24
|
+
Phrase: ${TOCKET_AGENT_PHRASE}
|
|
25
|
+
Optional TYPESAFE_API_KEY for live Jev; otherwise the stub
|
|
26
|
+
|
|
27
|
+
Tool-risk gate (file-first; Jev judges, workers execute):
|
|
28
|
+
tocket decide --from state.json --choice tool_gate:allow,block,ask --shadow
|
|
29
|
+
tocket work --from <decision>
|
|
30
|
+
tocket work --from <decision> --apply
|
|
31
|
+
|
|
32
|
+
A future --backend laya (local Apple Silicon) is not implemented yet.
|
|
33
|
+
`)
|
|
34
|
+
.option("--state <json|text>", "Inline state (JSON object/array or plain text)")
|
|
35
|
+
.option("--from <path.json>", "Load state from a JSON (or text) file")
|
|
36
|
+
.option("--choice <spec>", "Choice question as name:opt1,opt2,... (repeatable; batched in one request)", collect, [])
|
|
37
|
+
.option("--noul <name>", "Noul question name (repeatable; batched)", collect, [])
|
|
38
|
+
.option("--score <spec>", "Optional Score name or name:min,max (repeatable; batched)", collect, [])
|
|
39
|
+
.option("--fork <kind>", "Bounded fork: agent, model, tool, action, or human (default action)")
|
|
40
|
+
.option("--dry-run", "Force the deterministic stub and mark mode=dry-run (log-only)")
|
|
41
|
+
.option("--shadow", "Call Jev if TYPESAFE_API_KEY is set, but mark log-only (do not claim execution)")
|
|
42
|
+
.option("--confidence-threshold <n>", "Route research/write only at or above this confidence (default 0.85)")
|
|
43
|
+
.option("--id <id>", "Decision id used in the output filename")
|
|
44
|
+
.action(async (options) => {
|
|
45
|
+
const cwd = process.cwd();
|
|
46
|
+
try {
|
|
47
|
+
const { record, outPath } = await runDecide({
|
|
48
|
+
cwd,
|
|
49
|
+
state: options.state,
|
|
50
|
+
fromPath: options.from ? resolveFromPath(cwd, options.from) : undefined,
|
|
51
|
+
choices: options.choice,
|
|
52
|
+
nouls: options.noul,
|
|
53
|
+
scores: options.score,
|
|
54
|
+
fork: options.fork,
|
|
55
|
+
dryRun: options.dryRun === true,
|
|
56
|
+
shadow: options.shadow === true,
|
|
57
|
+
confidenceThreshold: parseConfidenceThreshold(options.confidenceThreshold),
|
|
58
|
+
id: options.id,
|
|
59
|
+
});
|
|
60
|
+
const rel = toRepoRelative(cwd, outPath);
|
|
61
|
+
console.log(success(formatDecideSummary(record, rel)));
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
65
|
+
console.error(themeError(message));
|
|
66
|
+
process.exitCode = err instanceof DecideError ? 2 : 1;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=decide.cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decide.cmd.js","sourceRoot":"","sources":["../../src/commands/decide.cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,5 +5,18 @@ export interface DiagResult {
|
|
|
5
5
|
}
|
|
6
6
|
export declare function checkContentHealth(basePath: string): DiagResult[];
|
|
7
7
|
export declare function checkGitTracking(cwd: string): DiagResult[];
|
|
8
|
+
export declare function formatAge(mtimeMs: number, now?: number): string;
|
|
9
|
+
export declare function findLatestDecision(cwd: string): {
|
|
10
|
+
path: string;
|
|
11
|
+
rel: string;
|
|
12
|
+
mtimeMs: number;
|
|
13
|
+
} | null;
|
|
14
|
+
export declare function checkTypesafeKeyPresent(env?: NodeJS.ProcessEnv): DiagResult;
|
|
15
|
+
export declare function checkNpmBin(): DiagResult;
|
|
16
|
+
/** Light notebook checks. Missing `.context/` is the only hard fail. */
|
|
17
|
+
export declare function checkNotebookLight(cwd: string, env?: NodeJS.ProcessEnv): {
|
|
18
|
+
results: DiagResult[];
|
|
19
|
+
hardFail: boolean;
|
|
20
|
+
};
|
|
8
21
|
export declare function checkStaleness(basePath: string): DiagResult | null;
|
|
9
22
|
export declare function registerDoctorCommand(program: Command): void;
|