@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.
Files changed (102) hide show
  1. package/README.md +233 -18
  2. package/dist/commands/agents-md.cmd.d.ts +2 -0
  3. package/dist/commands/agents-md.cmd.js +166 -0
  4. package/dist/commands/agents-md.cmd.js.map +1 -0
  5. package/dist/commands/decide.cmd.d.ts +2 -0
  6. package/dist/commands/decide.cmd.js +70 -0
  7. package/dist/commands/decide.cmd.js.map +1 -0
  8. package/dist/commands/doctor.cmd.d.ts +13 -0
  9. package/dist/commands/doctor.cmd.js +135 -11
  10. package/dist/commands/doctor.cmd.js.map +1 -1
  11. package/dist/commands/eject.cmd.d.ts +1 -1
  12. package/dist/commands/eject.cmd.js +3 -1
  13. package/dist/commands/eject.cmd.js.map +1 -1
  14. package/dist/commands/init.cmd.js +67 -13
  15. package/dist/commands/init.cmd.js.map +1 -1
  16. package/dist/commands/scaffold.cmd.d.ts +2 -0
  17. package/dist/commands/scaffold.cmd.js +118 -0
  18. package/dist/commands/scaffold.cmd.js.map +1 -0
  19. package/dist/commands/suite.cmd.d.ts +2 -0
  20. package/dist/commands/suite.cmd.js +387 -0
  21. package/dist/commands/suite.cmd.js.map +1 -0
  22. package/dist/commands/validate.cmd.js +1 -0
  23. package/dist/commands/validate.cmd.js.map +1 -1
  24. package/dist/commands/work.cmd.d.ts +2 -0
  25. package/dist/commands/work.cmd.js +48 -0
  26. package/dist/commands/work.cmd.js.map +1 -0
  27. package/dist/eval/decide-eval.d.ts +28 -0
  28. package/dist/eval/decide-eval.js +34 -0
  29. package/dist/eval/decide-eval.js.map +1 -0
  30. package/dist/eval/triage-eval.d.ts +46 -0
  31. package/dist/eval/triage-eval.js +175 -0
  32. package/dist/eval/triage-eval.js.map +1 -0
  33. package/dist/index.js +11 -1
  34. package/dist/index.js.map +1 -1
  35. package/dist/mcp/index.d.ts +2 -0
  36. package/dist/mcp/index.js +7 -0
  37. package/dist/mcp/index.js.map +1 -0
  38. package/dist/mcp/server.d.ts +4 -0
  39. package/dist/mcp/server.js +360 -0
  40. package/dist/mcp/server.js.map +1 -0
  41. package/dist/templates/memory-bank.d.ts +11 -0
  42. package/dist/templates/memory-bank.js +456 -329
  43. package/dist/templates/memory-bank.js.map +1 -1
  44. package/dist/tests/agents.test.js +73 -1
  45. package/dist/tests/agents.test.js.map +1 -1
  46. package/dist/tests/context.test.js +10 -1
  47. package/dist/tests/context.test.js.map +1 -1
  48. package/dist/tests/decide.test.d.ts +1 -0
  49. package/dist/tests/decide.test.js +483 -0
  50. package/dist/tests/decide.test.js.map +1 -0
  51. package/dist/tests/doctor.test.js +74 -1
  52. package/dist/tests/doctor.test.js.map +1 -1
  53. package/dist/tests/eject.test.js +3 -0
  54. package/dist/tests/eject.test.js.map +1 -1
  55. package/dist/tests/git.test.js +17 -0
  56. package/dist/tests/git.test.js.map +1 -1
  57. package/dist/tests/helpers.d.ts +6 -0
  58. package/dist/tests/helpers.js +13 -0
  59. package/dist/tests/helpers.js.map +1 -0
  60. package/dist/tests/helpers.test.d.ts +1 -0
  61. package/dist/tests/helpers.test.js +23 -0
  62. package/dist/tests/helpers.test.js.map +1 -0
  63. package/dist/tests/init.test.js +85 -5
  64. package/dist/tests/init.test.js.map +1 -1
  65. package/dist/tests/loop.test.d.ts +1 -0
  66. package/dist/tests/loop.test.js +153 -0
  67. package/dist/tests/loop.test.js.map +1 -0
  68. package/dist/tests/memory-bank.test.js +53 -1
  69. package/dist/tests/memory-bank.test.js.map +1 -1
  70. package/dist/tests/suite.test.d.ts +1 -0
  71. package/dist/tests/suite.test.js +199 -0
  72. package/dist/tests/suite.test.js.map +1 -0
  73. package/dist/tests/triage.test.d.ts +1 -0
  74. package/dist/tests/triage.test.js +152 -0
  75. package/dist/tests/triage.test.js.map +1 -0
  76. package/dist/tests/work.test.d.ts +1 -0
  77. package/dist/tests/work.test.js +276 -0
  78. package/dist/tests/work.test.js.map +1 -0
  79. package/dist/utils/agents.d.ts +25 -0
  80. package/dist/utils/agents.js +92 -0
  81. package/dist/utils/agents.js.map +1 -1
  82. package/dist/utils/appmaps.d.ts +65 -0
  83. package/dist/utils/appmaps.js +280 -0
  84. package/dist/utils/appmaps.js.map +1 -0
  85. package/dist/utils/context.d.ts +2 -0
  86. package/dist/utils/context.js +21 -0
  87. package/dist/utils/context.js.map +1 -1
  88. package/dist/utils/decide.d.ts +178 -0
  89. package/dist/utils/decide.js +614 -0
  90. package/dist/utils/decide.js.map +1 -0
  91. package/dist/utils/git.js +8 -1
  92. package/dist/utils/git.js.map +1 -1
  93. package/dist/utils/jev.d.ts +83 -0
  94. package/dist/utils/jev.js +190 -0
  95. package/dist/utils/jev.js.map +1 -0
  96. package/dist/utils/triage.d.ts +87 -0
  97. package/dist/utils/triage.js +241 -0
  98. package/dist/utils/triage.js.map +1 -0
  99. package/dist/utils/work.d.ts +72 -0
  100. package/dist/utils/work.js +225 -0
  101. package/dist/utils/work.js.map +1 -0
  102. package/package.json +53 -50
package/README.md CHANGED
@@ -5,32 +5,86 @@
5
5
 
6
6
  # Tocket
7
7
 
8
- **The Context Engineering Framework for Multi-Agent Workspaces**
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
- AI agents forget everything between sessions. When multiple agents work on the same codebase, they re-read files, duplicate work, and make conflicting decisions. Tocket fixes this with **shared context files that any agent can read** no vendor lock-in, no special integrations.
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 # Executor instructions (auto-detected per agent)
30
- GEMINI.md # Architect instructions (auto-detected per agent)
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
- # Scaffold a new workspace
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
- # Or just the essentials (3 files)
52
- npx @pedrocivita/tocket init --minimal
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
- # Configure your agents (optional defaults to Claude Code + Gemini)
55
- npx @pedrocivita/tocket config --architect "Gemini" --executor "Claude Code"
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
- # Or open the interactive dashboard
58
- npx @pedrocivita/tocket
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
- That's it. Your repo now has a Memory Bank. Every AI session starts by reading `.context/activeContext.md`.
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` | Deep workspace diagnostics (content health, git tracking, staleness) |
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
- |<-------- status report -----------|
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,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerAgentsMdCommand(program: Command): void;
@@ -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,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerDecideCommand(program: Command): void;
@@ -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;