agents-handoff 0.0.0-stage → 2.0.3
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/CHANGELOG.md +192 -0
- package/LICENSE +21 -0
- package/README.md +150 -2
- package/SKILL.md +147 -0
- package/capability-registry.json +27 -0
- package/docs/ARCHITECTURE.md +187 -0
- package/docs/CHANGELOG.md +196 -0
- package/docs/CLI.md +299 -0
- package/docs/COMPATIBILITY.md +124 -0
- package/docs/CONTRIBUTING.md +134 -0
- package/docs/FORMAT.md +185 -0
- package/docs/INSTALL.md +394 -0
- package/docs/INTEGRATION.md +188 -0
- package/docs/LEVEL4.md +202 -0
- package/docs/LEVEL5.md +96 -0
- package/docs/PERMISSIONS.md +145 -0
- package/docs/PROVENANCE.md +110 -0
- package/docs/SECURITY.md +93 -0
- package/docs/SESSIONS.md +97 -0
- package/docs/TROUBLESHOOTING.md +158 -0
- package/docs/UNINSTALL.md +148 -0
- package/docs/UPGRADE.md +177 -0
- package/docs/_config.yml +18 -0
- package/docs/_data/nav.yml +36 -0
- package/docs/_layouts/default.html +31 -0
- package/docs/assets/style.css +88 -0
- package/docs/index.md +92 -0
- package/docs/sessions.json +34 -0
- package/handoff.config.example.json +35 -0
- package/handoff.config.schema.json +117 -0
- package/install/CHANGELOG.md +48 -0
- package/install/README.md +76 -0
- package/install/install.mjs +1455 -0
- package/install/package.json +39 -0
- package/package.json +66 -4
- package/permission-policy.json +33 -0
- package/refs/ADAPTERS.md +33 -0
- package/refs/bootstrap.md +59 -0
- package/refs/brief-checklist.md +79 -0
- package/refs/handbook.md +58 -0
- package/refs/protocol.md +117 -0
- package/refs/roles.md +75 -0
- package/refs/validator.md +73 -0
- package/schemas/handoff.schema.json +275 -0
- package/skill.json +147 -0
- package/templates/HANDOFF.llm.schema.json +144 -0
- package/templates/HANDOFF.template.md +40 -0
- package/tests/acceptance/acceptance.yaml +209 -0
- package/tests/fixtures/minimal-transcript.jsonl +2 -0
- package/tools/agent-handoff.mjs +22 -0
- package/tools/agents-handoff.mjs +410 -0
- package/tools/capability-registry.mjs +120 -0
- package/tools/handoff.mjs +398 -0
- package/tools/handoff.test.mjs +668 -0
- package/tools/lib/handoff-root.mjs +161 -0
- package/tools/runtime-engine.mjs +330 -0
package/docs/UPGRADE.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Upgrade
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Upgrade
|
|
6
|
+
|
|
7
|
+
An upgrade replaces skill files. It does not touch the handoff folders, the configuration, or
|
|
8
|
+
anything you added next to them.
|
|
9
|
+
|
|
10
|
+
## Before upgrading
|
|
11
|
+
|
|
12
|
+
Confirm what is installed:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx agents-handoff --list
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
`--list` prints each installed location with its version and the number of manifest files
|
|
19
|
+
present. The version also appears as `version:` in the `SKILL.md` front matter of the
|
|
20
|
+
installation.
|
|
21
|
+
|
|
22
|
+
Back up handoff data before any manual change. The upgrade path keeps it, but a copy costs
|
|
23
|
+
nothing:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cp -r handoffs/ handoffs-backup/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Note any local edits to `handoff.config.json`, since a reinstall overwrites skill files but
|
|
30
|
+
leaves that file alone.
|
|
31
|
+
|
|
32
|
+
## Upgrade with the installer
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx agents-handoff --update
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
With no target flag, `--update` updates **every installation found on this machine**. That is
|
|
39
|
+
the whole answer to "keep my install current": a machine can hold the same skill in
|
|
40
|
+
`~/.claude/skills` and in `~/.agents/skills`, and updating only one of them is how the other
|
|
41
|
+
keeps running an old engine. Each installation is updated and reported on its own, and the run
|
|
42
|
+
ends with a summary naming the version it moved from and to:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
Update summary
|
|
46
|
+
✓ updated <dir>/agents-handoff — 2.0.2 → v2.0.3
|
|
47
|
+
✓ updated <dir>/agents-handoff — 2.0.2 → v2.0.3
|
|
48
|
+
✓ 2 of 2 installation(s) updated
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
When nothing is installed anywhere the installer can see, it says so and exits non-zero:
|
|
52
|
+
`Nothing to update: no agents-handoff installation found.`
|
|
53
|
+
|
|
54
|
+
The update then reinstalls: the skill files are copied over the existing installation and
|
|
55
|
+
overwrite the files of the same name. Files that are not part of the installation manifest —
|
|
56
|
+
`handoffs/`, `projects/`, `links/`, `.agent-handoff/`, `handoff.config.json`, `.env.example`, and
|
|
57
|
+
anything you added — are left in place. Nothing outside the manifest is read or rewritten.
|
|
58
|
+
|
|
59
|
+
Scope the update to one harness, or several, with the same flags install uses:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npx agents-handoff --update --claude # just Claude Code
|
|
63
|
+
npx agents-handoff --update --codex # just Codex CLI
|
|
64
|
+
npx agents-handoff --update --all # every harness found on this machine
|
|
65
|
+
npx agents-handoff --update --location project
|
|
66
|
+
npx agents-handoff --update --version 2.0.0
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`--all` covers the harnesses whose configuration directory exists here; a named harness is
|
|
70
|
+
updated whether or not that directory exists.
|
|
71
|
+
|
|
72
|
+
`--version` asks for a version, and the installer resolves it honestly: the tree beside the
|
|
73
|
+
installer is used when it **is** that version (or when nothing was requested), and when it is a
|
|
74
|
+
different version the requested tag's archive is fetched instead, with its sha256 recorded in
|
|
75
|
+
the install record's `source`. To switch versions, ask npm for the one you want
|
|
76
|
+
(`npx agents-handoff@<version>`), pass `--version <x>`, or install manually from that version's
|
|
77
|
+
tag archive. Confirm what is actually installed with `--verify`, which prints the version read
|
|
78
|
+
back from the installed `SKILL.md`, rather than trusting the request.
|
|
79
|
+
|
|
80
|
+
An update rewrites the install record as well, so `--verify --provenance` describes the new
|
|
81
|
+
state afterwards and reports the archive (with its sha256) when the files came from a download
|
|
82
|
+
rather than from a tree. The record's `package` block names the npm package and version the
|
|
83
|
+
installation should match; `npx agents-handoff --verify-package --record` fills in that
|
|
84
|
+
package's tarball hashes.
|
|
85
|
+
|
|
86
|
+
## Manual upgrade
|
|
87
|
+
|
|
88
|
+
Replace the skill files and keep the data:
|
|
89
|
+
|
|
90
|
+
1. Extract the release archive (`agents-handoff-v<version>.zip` from the
|
|
91
|
+
[releases page](https://github.com/Alot1z/agent-handoff/releases); the newest release carries
|
|
92
|
+
its own version in the file name) into a temporary directory.
|
|
93
|
+
2. Copy the skill files over the installation: `SKILL.md`, `skill.json`, the manifest JSON
|
|
94
|
+
files, `tools/`, `tools/lib/`, `schemas/`, `refs/`, `templates/`, `docs/`, `tests/`.
|
|
95
|
+
3. Do not delete `handoffs/`, `projects/`, `links/`, or `handoff.config.json`.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
unzip agents-handoff-v<version>.zip -d /tmp/agents-handoff-new
|
|
99
|
+
cp -r /tmp/agents-handoff-new/tools/ /tmp/agents-handoff-new/refs/ \
|
|
100
|
+
/tmp/agents-handoff-new/templates/ /tmp/agents-handoff-new/schemas/ \
|
|
101
|
+
/tmp/agents-handoff-new/docs/ "<install-path>/"
|
|
102
|
+
cp /tmp/agents-handoff-new/SKILL.md /tmp/agents-handoff-new/skill.json "<install-path>/"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## What an upgrade changes
|
|
106
|
+
|
|
107
|
+
| Changed | Unchanged |
|
|
108
|
+
|---|---|
|
|
109
|
+
| `tools/` — the engine and the dynamic runtime | `handoffs/` — your session data |
|
|
110
|
+
| `refs/`, `templates/`, `schemas/`, `docs/` | `projects/`, `links/` |
|
|
111
|
+
| `SKILL.md`, `skill.json`, manifest JSON files | `handoff.config.json` and your edits |
|
|
112
|
+
| `install/` — the installer itself | `HANDOFFS_ROOT`, if you use it |
|
|
113
|
+
| `.agents-handoff-install.json` — the install record, rewritten for the new version, including its `package` block | — |
|
|
114
|
+
| `.agent-handoff/` and any other store directory, whatever it is called | — |
|
|
115
|
+
|
|
116
|
+
Handoff folders are read from the handoff root in place, so an upgrade does not move or rewrite
|
|
117
|
+
them.
|
|
118
|
+
|
|
119
|
+
## After upgrading
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx agents-handoff --verify # every installation found
|
|
123
|
+
npx agents-handoff --verify --provenance
|
|
124
|
+
npx agents-handoff --verify-package --record # and prove it matches the published tarball
|
|
125
|
+
npx agents-handoff doctor
|
|
126
|
+
node "<install-path>/tools/handoff.mjs" config
|
|
127
|
+
node "<install-path>/tools/handoff.mjs" list
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`config` proves the engine starts and prints the handoff root it resolved. `list` proves the
|
|
131
|
+
engine still finds the handoff folders that were already there. `--verify --provenance` prints
|
|
132
|
+
the install record the verification was checked against — version, source, harness and the
|
|
133
|
+
file-set hash — which is the shortest way to prove an upgrade landed and left nothing behind.
|
|
134
|
+
|
|
135
|
+
The shipped test suite is a stronger check and does not touch existing handoffs when you point
|
|
136
|
+
it at a scratch root:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
HANDOFFS_ROOT=/tmp/handoff-check node "<install-path>/tools/handoff.test.mjs"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Read an existing handoff to confirm the data survived:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
node "<install-path>/tools/handoff.mjs" show <id-prefix>
|
|
146
|
+
node "<install-path>/tools/handoff.mjs" verify <id-prefix>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`verify <id-prefix>` recomputes the stored handoff's manifest hash, so it fails loudly if an
|
|
150
|
+
upgrade damaged the folder.
|
|
151
|
+
|
|
152
|
+
## Rollback
|
|
153
|
+
|
|
154
|
+
1. Restore the previous version's skill files: extract that version's release archive and copy
|
|
155
|
+
the skill files over the installation, as in the manual upgrade above.
|
|
156
|
+
2. Or reinstall the files that ship with the installer: `npx agents-handoff --force`.
|
|
157
|
+
3. Restore handoffs from your backup if you made one, and confirm with `--verify` and
|
|
158
|
+
`handoff.mjs list`.
|
|
159
|
+
|
|
160
|
+
## Troubleshooting
|
|
161
|
+
|
|
162
|
+
| Symptom | Cause and fix |
|
|
163
|
+
|---|---|
|
|
164
|
+
| `Not installed at <dir>` | `--path`, `--location` or a harness flag named a directory that holds no installation. Drop the flag to update every installation found, or check `--list`. |
|
|
165
|
+
| `Nothing to update: no agents-handoff installation found.` | Nothing to update anywhere the installer looks. Run `npx agents-handoff --all`, or name the directory with `--path`. |
|
|
166
|
+
| Reported version did not change | The installer uses the tree beside it when that tree **is** the requested version (or nothing was requested), so running it from a checkout installs that checkout. Use the published package, pass `--version <x>` to fetch that tag's archive, or check `--verify --provenance` to see which source the record names. |
|
|
167
|
+
| `verify-package` fails with `does NOT match … as published` | A file changed after the update. The check names it; reinstall with `--force`. |
|
|
168
|
+
| Verification fails after an upgrade | A file is missing or the engine cannot start. Reinstall with `--force` and read the failing check. |
|
|
169
|
+
| Handoffs no longer listed | The engine is reading a different root. Run `config` and compare it with where your handoffs live; set `HANDOFFS_ROOT` if needed. |
|
|
170
|
+
| `no provenance record` after upgrading | The record is written by installs from 2.0.3 on. Reinstall with `--force` to write one for this target. |
|
|
171
|
+
| Configuration was overwritten | `handoff.config.json` is preserved, but a manual copy step can still overwrite it. Restore your backup. |
|
|
172
|
+
|
|
173
|
+
## See also
|
|
174
|
+
|
|
175
|
+
- [INSTALL.md](INSTALL.md)
|
|
176
|
+
- [UNINSTALL.md](UNINSTALL.md)
|
|
177
|
+
- [../README.md](https://github.com/Alot1z/agent-handoff/blob/main/README.md)
|
package/docs/_config.yml
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
title: agents-handoff
|
|
2
|
+
description: Cross-harness capture and verified continuation for AI working sessions.
|
|
3
|
+
url: https://alot1z.github.io
|
|
4
|
+
# The site is served from the repository's Pages path, which follows the REPOSITORY name
|
|
5
|
+
# (agent-handoff), not the product name (agents-handoff).
|
|
6
|
+
baseurl: /agent-handoff
|
|
7
|
+
plugins:
|
|
8
|
+
- jekyll-relative-links
|
|
9
|
+
relative_links:
|
|
10
|
+
enabled: true
|
|
11
|
+
collections: false
|
|
12
|
+
defaults:
|
|
13
|
+
- scope:
|
|
14
|
+
path: ""
|
|
15
|
+
values:
|
|
16
|
+
layout: default
|
|
17
|
+
exclude:
|
|
18
|
+
- README.md
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
- title: Overview
|
|
2
|
+
path: /index.html
|
|
3
|
+
- title: Install
|
|
4
|
+
path: /INSTALL.html
|
|
5
|
+
- title: Upgrade
|
|
6
|
+
path: /UPGRADE.html
|
|
7
|
+
- title: Uninstall
|
|
8
|
+
path: /UNINSTALL.html
|
|
9
|
+
- title: Architecture
|
|
10
|
+
path: /ARCHITECTURE.html
|
|
11
|
+
- title: Command reference
|
|
12
|
+
path: /CLI.html
|
|
13
|
+
- title: Handoff format
|
|
14
|
+
path: /FORMAT.html
|
|
15
|
+
- title: Session index
|
|
16
|
+
path: /SESSIONS.html
|
|
17
|
+
- title: Integration
|
|
18
|
+
path: /INTEGRATION.html
|
|
19
|
+
- title: Runtime layer
|
|
20
|
+
path: /LEVEL4.html
|
|
21
|
+
- title: Dispatch
|
|
22
|
+
path: /LEVEL5.html
|
|
23
|
+
- title: Permissions
|
|
24
|
+
path: /PERMISSIONS.html
|
|
25
|
+
- title: Security
|
|
26
|
+
path: /SECURITY.html
|
|
27
|
+
- title: Compatibility
|
|
28
|
+
path: /COMPATIBILITY.html
|
|
29
|
+
- title: Provenance
|
|
30
|
+
path: /PROVENANCE.html
|
|
31
|
+
- title: Troubleshooting
|
|
32
|
+
path: /TROUBLESHOOTING.html
|
|
33
|
+
- title: Changelog
|
|
34
|
+
path: /CHANGELOG.html
|
|
35
|
+
- title: Contributing
|
|
36
|
+
path: /CONTRIBUTING.html
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>{% if page.title and page.title != site.title %}{{ page.title }} · {{ site.title }}{% else %}{{ site.title }}{% endif %}</title>
|
|
7
|
+
<meta name="description" content="{{ page.description | default: site.description }}">
|
|
8
|
+
<link rel="stylesheet" href="{{ '/assets/style.css' | relative_url }}">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<header class="top">
|
|
12
|
+
<a class="brand" href="{{ '/' | relative_url }}">{{ site.title }}</a>
|
|
13
|
+
<span class="tag">{{ site.description }}</span>
|
|
14
|
+
</header>
|
|
15
|
+
<div class="wrap">
|
|
16
|
+
<nav class="side">
|
|
17
|
+
<p class="navhead">Documentation</p>
|
|
18
|
+
<ul>
|
|
19
|
+
{% for d in site.data.nav %}<li><a href="{{ d.path | relative_url }}">{{ d.title }}</a></li>
|
|
20
|
+
{% endfor %}
|
|
21
|
+
</ul>
|
|
22
|
+
</nav>
|
|
23
|
+
<main>
|
|
24
|
+
{{ content }}
|
|
25
|
+
</main>
|
|
26
|
+
</div>
|
|
27
|
+
<footer class="foot">
|
|
28
|
+
MIT licensed · <a href="{{ site.baseurl }}">repository</a> · documentation source: the docs/ directory of this project
|
|
29
|
+
</footer>
|
|
30
|
+
</body>
|
|
31
|
+
</html>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--bg: #ffffff;
|
|
3
|
+
--fg: #1f2328;
|
|
4
|
+
--muted: #59636e;
|
|
5
|
+
--line: #d1d9e0;
|
|
6
|
+
--link: #0969da;
|
|
7
|
+
--code: #f6f8fa;
|
|
8
|
+
}
|
|
9
|
+
@media (prefers-color-scheme: dark) {
|
|
10
|
+
:root {
|
|
11
|
+
--bg: #0d1117;
|
|
12
|
+
--fg: #e6edf3;
|
|
13
|
+
--muted: #9198a1;
|
|
14
|
+
--line: #30363d;
|
|
15
|
+
--link: #4493f8;
|
|
16
|
+
--code: #161b22;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
* { box-sizing: border-box; }
|
|
20
|
+
body {
|
|
21
|
+
margin: 0;
|
|
22
|
+
background: var(--bg);
|
|
23
|
+
color: var(--fg);
|
|
24
|
+
font: 16px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
|
25
|
+
}
|
|
26
|
+
a { color: var(--link); text-decoration: none; }
|
|
27
|
+
a:hover { text-decoration: underline; }
|
|
28
|
+
.top {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-wrap: wrap;
|
|
31
|
+
align-items: baseline;
|
|
32
|
+
gap: 0.75rem;
|
|
33
|
+
padding: 1rem 1.5rem;
|
|
34
|
+
border-bottom: 1px solid var(--line);
|
|
35
|
+
}
|
|
36
|
+
.brand { font-weight: 600; font-size: 1.05rem; color: var(--fg); }
|
|
37
|
+
.tag { color: var(--muted); font-size: 0.85rem; }
|
|
38
|
+
.wrap {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: flex-start;
|
|
41
|
+
gap: 2.5rem;
|
|
42
|
+
max-width: 1080px;
|
|
43
|
+
margin: 0 auto;
|
|
44
|
+
padding: 2rem 1.5rem 4rem;
|
|
45
|
+
}
|
|
46
|
+
.side { flex: 0 0 180px; position: sticky; top: 1rem; }
|
|
47
|
+
.navhead {
|
|
48
|
+
margin: 0 0 0.5rem;
|
|
49
|
+
font-size: 0.75rem;
|
|
50
|
+
letter-spacing: 0.06em;
|
|
51
|
+
text-transform: uppercase;
|
|
52
|
+
color: var(--muted);
|
|
53
|
+
}
|
|
54
|
+
.side ul { list-style: none; margin: 0; padding: 0; }
|
|
55
|
+
.side li { margin: 0.15rem 0; }
|
|
56
|
+
.side a { font-size: 0.9rem; }
|
|
57
|
+
main { flex: 1 1 auto; min-width: 0; }
|
|
58
|
+
main h1 { font-size: 1.75rem; margin: 0 0 1rem; }
|
|
59
|
+
main h2 { font-size: 1.2rem; margin: 2rem 0 0.6rem; padding-bottom: 0.25rem; border-bottom: 1px solid var(--line); }
|
|
60
|
+
main h3 { font-size: 1rem; margin: 1.5rem 0 0.4rem; }
|
|
61
|
+
code {
|
|
62
|
+
background: var(--code);
|
|
63
|
+
padding: 0.1em 0.35em;
|
|
64
|
+
border-radius: 5px;
|
|
65
|
+
font-size: 0.88em;
|
|
66
|
+
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
|
|
67
|
+
}
|
|
68
|
+
pre {
|
|
69
|
+
background: var(--code);
|
|
70
|
+
padding: 0.85rem 1rem;
|
|
71
|
+
border-radius: 6px;
|
|
72
|
+
overflow-x: auto;
|
|
73
|
+
}
|
|
74
|
+
pre code { background: none; padding: 0; }
|
|
75
|
+
table { border-collapse: collapse; width: 100%; margin: 1rem 0; font-size: 0.92rem; }
|
|
76
|
+
th, td { border: 1px solid var(--line); padding: 0.4rem 0.6rem; text-align: left; vertical-align: top; }
|
|
77
|
+
th { background: var(--code); }
|
|
78
|
+
blockquote { margin: 1rem 0; padding: 0 1rem; border-left: 3px solid var(--line); color: var(--muted); }
|
|
79
|
+
.foot {
|
|
80
|
+
border-top: 1px solid var(--line);
|
|
81
|
+
padding: 1rem 1.5rem 2rem;
|
|
82
|
+
color: var(--muted);
|
|
83
|
+
font-size: 0.85rem;
|
|
84
|
+
}
|
|
85
|
+
@media (max-width: 720px) {
|
|
86
|
+
.wrap { flex-direction: column; gap: 1rem; }
|
|
87
|
+
.side { position: static; }
|
|
88
|
+
}
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: agents-handoff
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# agents-handoff documentation
|
|
6
|
+
|
|
7
|
+
agents-handoff turns an AI working session — chat turns, tool calls, reasoning, however the
|
|
8
|
+
client stored it — into a folder of plain files that a different agent, a different harness,
|
|
9
|
+
or a colleague can read and continue from without the original chat. It builds from a
|
|
10
|
+
transcript or an adapter export, keeps a hash chain so a handoff can be re-verified, and
|
|
11
|
+
merges later turns into the same session instead of duplicating it.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# 1. Install the skill into every harness found on this machine
|
|
17
|
+
npx agents-handoff --all
|
|
18
|
+
|
|
19
|
+
# 2. Build a handoff from a transcript
|
|
20
|
+
node tools/handoff.mjs build --source transcript.jsonl --project my-project
|
|
21
|
+
|
|
22
|
+
# 3. Find it, read it, check it
|
|
23
|
+
node tools/handoff.mjs list
|
|
24
|
+
node tools/handoff.mjs show <id-prefix>
|
|
25
|
+
node tools/handoff.mjs verify <id-prefix>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`build` also accepts `--session`, `--harness`, `--model` and `--objective`. Run
|
|
29
|
+
`node tools/handoff.mjs config` to see which store root the engine resolved and why.
|
|
30
|
+
|
|
31
|
+
`--all` installs into every harness present on the machine; `--claude`, `--codex`, `--agents`
|
|
32
|
+
and `--skills-dir <dir>` pick one or several instead, and `npx agents-handoff --update` brings
|
|
33
|
+
every copy on the machine up to date in one run. `npx agents-handoff --verify-package` then
|
|
34
|
+
proves the copy on disk is identical to the tarball npm is serving for its version, while
|
|
35
|
+
`npx agents-handoff --doctor` reports what is installed where and whether each copy still
|
|
36
|
+
matches the record written when it was installed. The installer's full surface is in
|
|
37
|
+
[CLI.md](CLI.md) and [INSTALL.md](INSTALL.md).
|
|
38
|
+
|
|
39
|
+
## Where to start
|
|
40
|
+
|
|
41
|
+
| If you want to… | Read |
|
|
42
|
+
|---|---|
|
|
43
|
+
| install it | [INSTALL.md](INSTALL.md) |
|
|
44
|
+
| prove an install matches the published package | [INSTALL.md](INSTALL.md) and [CLI.md](CLI.md) |
|
|
45
|
+
| understand how the pieces fit | [ARCHITECTURE.md](ARCHITECTURE.md) |
|
|
46
|
+
| look up a command, flag or exit code | [CLI.md](CLI.md) |
|
|
47
|
+
| know exactly what a handoff folder holds | [FORMAT.md](FORMAT.md) |
|
|
48
|
+
| see captured sessions, and check them | [SESSIONS.md](SESSIONS.md) |
|
|
49
|
+
| fix something that is not working | [TROUBLESHOOTING.md](TROUBLESHOOTING.md) |
|
|
50
|
+
| feed it a transcript from your own tool | [INTEGRATION.md](INTEGRATION.md) and [../refs/ADAPTERS.md](https://github.com/Alot1z/agent-handoff/blob/main/refs/ADAPTERS.md) |
|
|
51
|
+
| understand what the hashes prove | [PROVENANCE.md](PROVENANCE.md) |
|
|
52
|
+
|
|
53
|
+
## All pages
|
|
54
|
+
|
|
55
|
+
| Document | Contents |
|
|
56
|
+
|---|---|
|
|
57
|
+
| [INSTALL.md](INSTALL.md) | Installer commands, install locations, requirements |
|
|
58
|
+
| [UPGRADE.md](UPGRADE.md) | Updating an installation, pinning a version, what a version change touches |
|
|
59
|
+
| [UNINSTALL.md](UNINSTALL.md) | Removing an installation, and which files are deliberately kept |
|
|
60
|
+
| [ARCHITECTURE.md](ARCHITECTURE.md) | The layers, the data flow, the store root, the write-safety discipline, the boundaries |
|
|
61
|
+
| [CLI.md](CLI.md) | Every executable, verb, flag, exit code, environment variable and file written |
|
|
62
|
+
| [FORMAT.md](FORMAT.md) | Handoff folder layout, every file in it, the manifest and the schemas |
|
|
63
|
+
| [SESSIONS.md](SESSIONS.md) | Session index: a sample store, its captured sessions, and how to verify and re-render them. The same rows are published as [sessions.json](sessions.json) (schema `1.0-session-feed`) for anything that would rather read data than markdown, and the page filters in the browser |
|
|
64
|
+
| [INTEGRATION.md](INTEGRATION.md) | Embedding the engine, configuration and environment, CI and pipeline use |
|
|
65
|
+
| [LEVEL4.md](LEVEL4.md) | Dynamic runtime layer: runtime verbs, gates and promotion |
|
|
66
|
+
| [LEVEL5.md](LEVEL5.md) | Collaborative dispatch: routing a handoff to another agent |
|
|
67
|
+
| [PERMISSIONS.md](PERMISSIONS.md) | Permission levels, risk classes, and the policy file |
|
|
68
|
+
| [SECURITY.md](SECURITY.md) | What is read and written, secrets, malicious input, guarantees not made |
|
|
69
|
+
| [COMPATIBILITY.md](COMPATIBILITY.md) | Platforms, Node versions, input formats, exit codes |
|
|
70
|
+
| [PROVENANCE.md](PROVENANCE.md) | The hash chain, how to verify it, what it cannot prove |
|
|
71
|
+
| [TROUBLESHOOTING.md](TROUBLESHOOTING.md) | Symptom, cause and fix, keyed to the real exit codes |
|
|
72
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | Test suite, project layout, how to add an adapter |
|
|
73
|
+
| [Changelog](https://github.com/Alot1z/agent-handoff/blob/main/CHANGELOG.md) | What changed in each release, and how to add an entry |
|
|
74
|
+
| [../refs/ADAPTERS.md](https://github.com/Alot1z/agent-handoff/blob/main/refs/ADAPTERS.md) | Canonical input shape and how each session source maps onto it |
|
|
75
|
+
|
|
76
|
+
## Engine commands
|
|
77
|
+
|
|
78
|
+
| Command | Effect |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `build --source <file>` | Build or update a handoff from a transcript |
|
|
81
|
+
| `--handoff --source <file>` | Alias of `build` |
|
|
82
|
+
| `list [project-or-prefix]` | List sessions, newest first |
|
|
83
|
+
| `show <id-prefix>` | Print the rendered brief |
|
|
84
|
+
| `verify <id-prefix>` | Re-check the hash chain |
|
|
85
|
+
| `rename <id-prefix> <project>` | Move a session to another project |
|
|
86
|
+
| `retitle <id-prefix> <name>` | Give a session a readable name |
|
|
87
|
+
| `config` | Report the resolved store root, its source and the schema path |
|
|
88
|
+
|
|
89
|
+
Zero dependencies, Node 18 or newer. [CLI.md](CLI.md) has the full command surface, including
|
|
90
|
+
the runtime layer, bounded execution and the capability registry. See
|
|
91
|
+
[../README.md](https://github.com/Alot1z/agent-handoff/blob/main/README.md) for the repository overview and [../SKILL.md](https://github.com/Alot1z/agent-handoff/blob/main/SKILL.md) for
|
|
92
|
+
the skill definition.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "1.0-session-feed",
|
|
3
|
+
"generated_by": ".github/scripts/build-sessions-index.mjs",
|
|
4
|
+
"store": "examples/sessions",
|
|
5
|
+
"index_source": "INDEX.json",
|
|
6
|
+
"as_of": "2026-10-08T22:53:03.964Z",
|
|
7
|
+
"count": 2,
|
|
8
|
+
"projects": 2,
|
|
9
|
+
"failed": 0,
|
|
10
|
+
"sessions": [
|
|
11
|
+
{
|
|
12
|
+
"id": "typescript-project-setup",
|
|
13
|
+
"project": "demo",
|
|
14
|
+
"harness": "claude-code",
|
|
15
|
+
"model": "claude-3-5-sonnet",
|
|
16
|
+
"turns": 11,
|
|
17
|
+
"revisions": 1,
|
|
18
|
+
"updated": "2026-10-08T22:53:03.865Z",
|
|
19
|
+
"manifest_sha256": "141e232eb2ad668f59d746828517e646a5cbe2bc914dd976df3c43c209214d3c",
|
|
20
|
+
"integrity": "pass"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "fixture-roundtrip",
|
|
24
|
+
"project": "smoke-test",
|
|
25
|
+
"harness": "codex",
|
|
26
|
+
"model": "gpt-5-codex",
|
|
27
|
+
"turns": 2,
|
|
28
|
+
"revisions": 1,
|
|
29
|
+
"updated": "2026-10-08T22:53:03.964Z",
|
|
30
|
+
"manifest_sha256": "a81d076e3334b8341f2829d0f38daf2cdbaf667269a9909dc523797c74e46ce5",
|
|
31
|
+
"integrity": "pass"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./handoff.config.schema.json",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"handoff_dir": "handoffs/",
|
|
5
|
+
"project_name": null,
|
|
6
|
+
"auto_capture": false,
|
|
7
|
+
"max_brief_tokens": 30000,
|
|
8
|
+
"exclude_from_handoff": [
|
|
9
|
+
"node_modules/",
|
|
10
|
+
".git/",
|
|
11
|
+
"dist/",
|
|
12
|
+
"build/",
|
|
13
|
+
"*.token",
|
|
14
|
+
"*.key",
|
|
15
|
+
"*.pem",
|
|
16
|
+
".env",
|
|
17
|
+
"*.log"
|
|
18
|
+
],
|
|
19
|
+
"capture": {
|
|
20
|
+
"include_tool_outputs": true,
|
|
21
|
+
"truncate_tool_outputs": false,
|
|
22
|
+
"max_tool_output_length": 100000
|
|
23
|
+
},
|
|
24
|
+
"linking": {
|
|
25
|
+
"enabled": true,
|
|
26
|
+
"min_overlap_score": 0.06
|
|
27
|
+
},
|
|
28
|
+
"integrity": {
|
|
29
|
+
"sha256_manifest": true,
|
|
30
|
+
"verify_on_read": false
|
|
31
|
+
},
|
|
32
|
+
"storage": {
|
|
33
|
+
"type": "filesystem"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://github.com/Alot1z/agent-handoff/handoff.config.schema.json",
|
|
4
|
+
"title": "Agent Handoff Configuration",
|
|
5
|
+
"description": "Schema for handoff.config.json — where handoffs are stored, and how a session is captured. Copy handoff.config.example.json to your project root as handoff.config.json to opt in; with no config file the engine keeps its default store. HANDOFFS_ROOT always overrides anything set here.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "Optional pointer to this schema, for editor completion."
|
|
12
|
+
},
|
|
13
|
+
"version": {
|
|
14
|
+
"type": "integer",
|
|
15
|
+
"enum": [1],
|
|
16
|
+
"default": 1,
|
|
17
|
+
"description": "Config format version."
|
|
18
|
+
},
|
|
19
|
+
"handoff_dir": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"minLength": 1,
|
|
22
|
+
"default": "handoffs/",
|
|
23
|
+
"description": "Where handoffs are stored. Relative paths resolve against the directory holding this file; absolute paths are used as-is.",
|
|
24
|
+
"examples": ["handoffs/", ".context/handoffs/", "/srv/handoffs/"]
|
|
25
|
+
},
|
|
26
|
+
"project_name": {
|
|
27
|
+
"type": ["string", "null"],
|
|
28
|
+
"default": null,
|
|
29
|
+
"description": "Project used for grouping handoffs. Auto-detected when null."
|
|
30
|
+
},
|
|
31
|
+
"auto_capture": {
|
|
32
|
+
"type": "boolean",
|
|
33
|
+
"default": false,
|
|
34
|
+
"description": "Accepted and validated; reserved — no tool auto-captures sessions yet."
|
|
35
|
+
},
|
|
36
|
+
"max_brief_tokens": {
|
|
37
|
+
"type": "integer",
|
|
38
|
+
"minimum": 1000,
|
|
39
|
+
"maximum": 100000,
|
|
40
|
+
"default": 30000,
|
|
41
|
+
"description": "Accepted and validated; reserved — brief truncation is not implemented."
|
|
42
|
+
},
|
|
43
|
+
"exclude_from_handoff": {
|
|
44
|
+
"type": "array",
|
|
45
|
+
"items": { "type": "string" },
|
|
46
|
+
"default": [
|
|
47
|
+
"node_modules/",
|
|
48
|
+
".git/",
|
|
49
|
+
"dist/",
|
|
50
|
+
"build/",
|
|
51
|
+
"*.token",
|
|
52
|
+
"*.key",
|
|
53
|
+
"*.pem",
|
|
54
|
+
".env",
|
|
55
|
+
"*.log"
|
|
56
|
+
],
|
|
57
|
+
"description": "Accepted and validated; reserved — the engine copies no project trees, so nothing is filtered yet."
|
|
58
|
+
},
|
|
59
|
+
"capture": {
|
|
60
|
+
"type": "object",
|
|
61
|
+
"additionalProperties": false,
|
|
62
|
+
"default": {},
|
|
63
|
+
"properties": {
|
|
64
|
+
"exclude_patterns": { "type": "array", "items": { "type": "string" } },
|
|
65
|
+
"include_tool_outputs": { "type": "boolean", "default": true },
|
|
66
|
+
"truncate_tool_outputs": { "type": "boolean", "default": false },
|
|
67
|
+
"max_tool_output_length": { "type": "integer", "default": 100000, "minimum": 0 }
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"linking": {
|
|
71
|
+
"type": "object",
|
|
72
|
+
"additionalProperties": false,
|
|
73
|
+
"default": {},
|
|
74
|
+
"properties": {
|
|
75
|
+
"enabled": {
|
|
76
|
+
"type": "boolean",
|
|
77
|
+
"default": true,
|
|
78
|
+
"description": "HONOURED: when false, cross-project link notes are not written."
|
|
79
|
+
},
|
|
80
|
+
"min_overlap_score": {
|
|
81
|
+
"type": "number",
|
|
82
|
+
"minimum": 0,
|
|
83
|
+
"maximum": 1,
|
|
84
|
+
"default": 0.06,
|
|
85
|
+
"description": "Accepted and validated; reserved — the engine uses its built-in 0.06 threshold."
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"integrity": {
|
|
90
|
+
"type": "object",
|
|
91
|
+
"additionalProperties": false,
|
|
92
|
+
"default": {},
|
|
93
|
+
"properties": {
|
|
94
|
+
"sha256_manifest": { "type": "boolean", "default": true },
|
|
95
|
+
"verify_on_read": { "type": "boolean", "default": false }
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"storage": {
|
|
99
|
+
"type": "object",
|
|
100
|
+
"additionalProperties": false,
|
|
101
|
+
"default": {},
|
|
102
|
+
"properties": {
|
|
103
|
+
"type": {
|
|
104
|
+
"type": "string",
|
|
105
|
+
"enum": ["filesystem", "sqlite"],
|
|
106
|
+
"default": "filesystem",
|
|
107
|
+
"description": "Only filesystem is implemented; sqlite validates but is not honoured."
|
|
108
|
+
},
|
|
109
|
+
"path": {
|
|
110
|
+
"type": "string",
|
|
111
|
+
"minLength": 1,
|
|
112
|
+
"description": "HONOURED and beats handoff_dir: an explicit store path."
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|