agents-handoff 0.0.0-stage → 2.0.2
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 +150 -0
- package/LICENSE +21 -0
- package/README.md +110 -2
- package/SKILL.md +147 -0
- package/capability-registry.json +27 -0
- package/docs/ARCHITECTURE.md +164 -0
- package/docs/CHANGELOG.md +151 -0
- package/docs/CLI.md +196 -0
- package/docs/COMPATIBILITY.md +124 -0
- package/docs/CONTRIBUTING.md +134 -0
- package/docs/FORMAT.md +157 -0
- package/docs/INSTALL.md +179 -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 +83 -0
- package/docs/SECURITY.md +93 -0
- package/docs/SESSIONS.md +66 -0
- package/docs/TROUBLESHOOTING.md +158 -0
- package/docs/UNINSTALL.md +122 -0
- package/docs/UPGRADE.md +139 -0
- package/docs/_config.yml +16 -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 +83 -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 +856 -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 +410 -0
- package/tools/capability-registry.mjs +120 -0
- package/tools/handoff.mjs +398 -0
- package/tools/handoff.test.mjs +465 -0
- package/tools/lib/handoff-root.mjs +161 -0
- package/tools/runtime-engine.mjs +330 -0
package/docs/SESSIONS.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Session index
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Session index
|
|
6
|
+
|
|
7
|
+
A handoff store is a directory of captured sessions. This page is generated from the
|
|
8
|
+
sample store in [`examples/sessions/`](https://github.com/Alot1z/agent-handoff/tree/main/examples/sessions), whose sessions the
|
|
9
|
+
engine built from the two transcripts this repository ships. Nothing here is written by hand:
|
|
10
|
+
the table below is a rendering of that store, re-checked on every build.
|
|
11
|
+
|
|
12
|
+
| Project | Session | Harness | Turns | Revision | Manifest sha256 | Integrity |
|
|
13
|
+
|---|---|---|---:|---:|---|---|
|
|
14
|
+
| demo | `typescript-project-setup` | claude-code | 11 | 1 | `141e232eb2ad…` | PASS |
|
|
15
|
+
| smoke-test | `fixture-roundtrip` | codex | 2 | 1 | `a81d076e3334…` | PASS |
|
|
16
|
+
|
|
17
|
+
**2 session(s) across 2 project(s): all verified.**
|
|
18
|
+
|
|
19
|
+
## What each column proves
|
|
20
|
+
|
|
21
|
+
| Column | Where it comes from |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Project, Session | The store layout: `projects/<project>/<session>/` |
|
|
24
|
+
| Harness | `harness` in the session manifest — what produced the transcript |
|
|
25
|
+
| Turns | Lines in `timeline.jsonl`, checked against `turn_count` in the manifest |
|
|
26
|
+
| Revision | `revisions` in the manifest. A rebuild that appends turns raises it; it never forks a session |
|
|
27
|
+
| Manifest sha256 | `manifest_sha256`, the hash of the manifest with that field removed |
|
|
28
|
+
| Integrity | `PASS` when the manifest hash matches, the turn count matches and `HANDOFF.llm.json` parses |
|
|
29
|
+
|
|
30
|
+
## Verify a session yourself
|
|
31
|
+
|
|
32
|
+
Point the engine at the sample store and ask it the same question this page answers:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# the store this page is rendered from
|
|
36
|
+
HANDOFFS_ROOT=examples/sessions node tools/handoff.mjs list
|
|
37
|
+
HANDOFFS_ROOT=examples/sessions node tools/handoff.mjs verify typescript-project-setup
|
|
38
|
+
HANDOFFS_ROOT=examples/sessions node tools/handoff.mjs verify fixture-roundtrip
|
|
39
|
+
|
|
40
|
+
# your own store
|
|
41
|
+
HANDOFFS_ROOT=/path/to/your/store node tools/handoff.mjs list
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`verify` exits non-zero the moment one of the three checks fails, so it works as a gate:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
HANDOFFS_ROOT=examples/sessions node tools/handoff.mjs verify typescript-project-setup || echo "do not resume this session"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Generate this page from your own store
|
|
51
|
+
|
|
52
|
+
The generator is part of this repository, and it reads any store in the format above:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
node .github/scripts/build-sessions-index.mjs --store examples/sessions --out docs/SESSIONS.md
|
|
56
|
+
node .github/scripts/build-sessions-index.mjs --check # exit 1 when the page is stale
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`--check` is wired into CI, so a store that changes without the page changing fails the build
|
|
60
|
+
instead of publishing a table that no longer matches what the engine can read.
|
|
61
|
+
|
|
62
|
+
## Next
|
|
63
|
+
|
|
64
|
+
- The file-by-file contract for a session folder is in [FORMAT.md](FORMAT.md).
|
|
65
|
+
- The commands that read and write a store are in [CLI.md](CLI.md).
|
|
66
|
+
- What the hashes prove, and what they cannot, is in [PROVENANCE.md](PROVENANCE.md).
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Troubleshooting
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Troubleshooting
|
|
6
|
+
|
|
7
|
+
Each entry names the symptom, the cause, and the fix. Exit codes are the ones documented in
|
|
8
|
+
[CLI.md](CLI.md).
|
|
9
|
+
|
|
10
|
+
## Nothing is listed
|
|
11
|
+
|
|
12
|
+
**Symptom:** `handoff: no handoffs yet`.
|
|
13
|
+
|
|
14
|
+
**Cause:** no build has run against the store being read, or the build wrote to a different
|
|
15
|
+
store.
|
|
16
|
+
|
|
17
|
+
**Fix:** check which store the engine resolved, and which rule chose it:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
node tools/handoff.mjs config
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The rule is one of `env`, `config`, `discover`, `default`. If it is not the store you
|
|
24
|
+
expected, set `HANDOFFS_ROOT` for the run, or add a `handoff.config.json` at the project
|
|
25
|
+
root. Resolution order is in [FORMAT.md](FORMAT.md#where-handoffs-live).
|
|
26
|
+
|
|
27
|
+
## `build` exits 2
|
|
28
|
+
|
|
29
|
+
**Cause:** `--source` was not given, or the value was consumed as another flag.
|
|
30
|
+
|
|
31
|
+
**Fix:** `build` requires it:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
node tools/handoff.mjs build --source transcript.jsonl --project my-project
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## `build` exits 4 after reading the file
|
|
38
|
+
|
|
39
|
+
**Cause:** no turn parsed. A `.jsonl` source is parsed one line at a time and a line that
|
|
40
|
+
does not parse is skipped; a text source needs a line starting with `user:`, `human:`,
|
|
41
|
+
`assistant:`, `ai:`, `system:` or `tool:`.
|
|
42
|
+
|
|
43
|
+
**Fix:** inspect the first few lines of the source. If the transcript is JSONL but the fields
|
|
44
|
+
are named differently, an adapter is what you want — see [ADAPTERS.md](https://github.com/Alot1z/agent-handoff/blob/main/refs/ADAPTERS.md)
|
|
45
|
+
for the canonical shape, and [INTEGRATION.md](INTEGRATION.md) for mapping a new source onto
|
|
46
|
+
it.
|
|
47
|
+
|
|
48
|
+
## `verify` prints FAIL
|
|
49
|
+
|
|
50
|
+
**Cause:** one of three things — the manifest was edited by hand after the build, the
|
|
51
|
+
timeline line count no longer matches `turn_count`, or `HANDOFF.llm.json` does not parse.
|
|
52
|
+
|
|
53
|
+
**Fix:** do not edit a handoff by hand. Rebuild from the same source:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
node tools/handoff.mjs build --source <original source> --session <id>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
A rebuild re-seals the manifest and rewrites the renders. If the original source is gone,
|
|
60
|
+
the handoff cannot be re-verified, and the honest answer is to say so rather than patch the
|
|
61
|
+
hash.
|
|
62
|
+
|
|
63
|
+
## `show`, `verify`, `rename` or `retitle` exits 3 or 4
|
|
64
|
+
|
|
65
|
+
**Cause:** 3 means the prefix matched more than one session; 4 means it matched none.
|
|
66
|
+
|
|
67
|
+
**Fix:** run `handoff.mjs list`, then use a longer prefix.
|
|
68
|
+
|
|
69
|
+
## `config` exits 2 and names a config file
|
|
70
|
+
|
|
71
|
+
**Cause:** a `handoff.config.json` was found but is not valid against
|
|
72
|
+
`handoff.config.schema.json`. The engine refuses to fall back to another store, because
|
|
73
|
+
falling back would write somewhere other than the configured location.
|
|
74
|
+
|
|
75
|
+
**Fix:** correct the file against the schema, or delete it to fall through to the
|
|
76
|
+
`handoffs/` convention.
|
|
77
|
+
|
|
78
|
+
## A runtime command exits 3 with "capture already in flight"
|
|
79
|
+
|
|
80
|
+
**Cause:** another run holds the lock for that project and session. Locks are files in
|
|
81
|
+
`<root>/.locks/`, named after a hash of the operation target.
|
|
82
|
+
|
|
83
|
+
**Fix:** wait for the other run. If a previous process was killed abruptly, it can leave a
|
|
84
|
+
lock file behind; the file is normally removed when the run finishes, so a lock that is
|
|
85
|
+
still present after every process has stopped can be deleted by hand.
|
|
86
|
+
|
|
87
|
+
## `dispatch` or `merge` produced something that fails the gate
|
|
88
|
+
|
|
89
|
+
**Cause:** by design. A `merge` writes a timeline with no brief, no payload and no
|
|
90
|
+
`TOOLS.md`, so `verify-gate` fails it on `payload` and `contract` until a brief is written
|
|
91
|
+
for the merged session. `index` reports the same sessions as stale.
|
|
92
|
+
|
|
93
|
+
**Fix:** write the brief for the merged session, then re-run `verify-gate`. A brief needs the
|
|
94
|
+
seven contract fields — `RESULT`, `WHAT_CHANGED`, `VALIDATION`, `EVIDENCE`, `BLOCKERS`,
|
|
95
|
+
`RISKS`, `FOLLOW_UP` — each starting a line.
|
|
96
|
+
|
|
97
|
+
## `verify-gate` exits 0 but the verdict says REJECTED
|
|
98
|
+
|
|
99
|
+
**Cause:** not a bug. `verify-gate` exits 0 for both verdicts so that "the gate ran" and
|
|
100
|
+
"the gate passed" stay distinguishable. Read `ok` or `verdict` from the JSON.
|
|
101
|
+
|
|
102
|
+
**Fix:** branch on the verdict in any script that calls it. The same applies to `promote`,
|
|
103
|
+
which prints the gate result but stamps the manifest either way.
|
|
104
|
+
|
|
105
|
+
## `promote` stamped a session that is not verified
|
|
106
|
+
|
|
107
|
+
**Cause:** expected behaviour, and stated in the command reference. Promotion is a local
|
|
108
|
+
stamp, not an enforcement.
|
|
109
|
+
|
|
110
|
+
**Fix:** run `verify-gate` first and only call `promote` when the verdict is `VERIFIED`.
|
|
111
|
+
|
|
112
|
+
## `capability-registry check` fails with `unknown`
|
|
113
|
+
|
|
114
|
+
**Cause:** a capability declares a probe kind with no implementation, or declares no target
|
|
115
|
+
or command for its kind. The registry reports `unknown` with the reason instead of guessing.
|
|
116
|
+
|
|
117
|
+
**Fix:** read the evidence line for the capability. `unknown` for a required capability is
|
|
118
|
+
treated as a failure on purpose: an unanswered question is not a pass.
|
|
119
|
+
|
|
120
|
+
## `runtime-engine run` exits 3
|
|
121
|
+
|
|
122
|
+
**Cause:** `DENIED`. An explicit denial, a personal-data path, an unknown risk class or an
|
|
123
|
+
unknown grant all land here. A personal-data or denied target is refused at any risk class.
|
|
124
|
+
|
|
125
|
+
**Fix:** inspect the decision before changing anything:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
node tools/runtime-engine.mjs evaluate --risk R1 --target <path> --json
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The policy itself is [permission-policy.json](https://github.com/Alot1z/agent-handoff/blob/main/permission-policy.json); read
|
|
132
|
+
[PERMISSIONS.md](PERMISSIONS.md) for the levels.
|
|
133
|
+
|
|
134
|
+
## `runtime-engine resume` exits 4
|
|
135
|
+
|
|
136
|
+
**Cause:** there is no checkpoint to resume from, either because no job ran for that session
|
|
137
|
+
or because the session name does not match. Exit 5 means a checkpoint exists but is corrupt
|
|
138
|
+
or its integrity seal does not match.
|
|
139
|
+
|
|
140
|
+
**Fix:** run `status` for the session to see the durable state, then start a new job.
|
|
141
|
+
|
|
142
|
+
## The documentation site is missing a page, or a link 404s
|
|
143
|
+
|
|
144
|
+
**Cause:** the site is built from `docs/`. A page not listed in `docs/_data/nav.yml` does not
|
|
145
|
+
appear in the navigation, and a relative link that points at a file outside `docs/` does not
|
|
146
|
+
resolve in the built site.
|
|
147
|
+
|
|
148
|
+
**Fix:** add the page under `docs/`, add it to `nav.yml`, and run the check CI runs:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
node .github/scripts/check-docs.mjs
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Node version
|
|
155
|
+
|
|
156
|
+
The tools require Node.js 18 or newer and use only built-in modules. `node --version` below
|
|
157
|
+
18 is the only unsupported configuration; there is no build step and no dependencies to
|
|
158
|
+
reinstall. Platform notes are in [COMPATIBILITY.md](COMPATIBILITY.md).
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Uninstall
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Uninstall
|
|
6
|
+
|
|
7
|
+
Uninstalling removes the skill files. Your handoffs and your configuration stay where they are.
|
|
8
|
+
|
|
9
|
+
## Quick uninstall
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx agents-handoff --remove
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Removal asks for confirmation first:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
This will remove agent-handoff from:
|
|
19
|
+
<install-path>
|
|
20
|
+
|
|
21
|
+
Your handoffs (projects/, handoffs/, links/) will NOT be deleted.
|
|
22
|
+
Configuration (handoff.config.json) will NOT be deleted.
|
|
23
|
+
|
|
24
|
+
Continue? (y/N)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Answer `y` to proceed. In a non-interactive shell the prompt is skipped and nothing is removed;
|
|
28
|
+
the installer prints `Non-interactive mode, use --force to skip confirmation` instead.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx agents-handoff --remove --force
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Options
|
|
35
|
+
|
|
36
|
+
| Option | Effect |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `--remove` | Remove the installation (interactive confirmation). |
|
|
39
|
+
| `--force`, `-f` | Skip the confirmation, and delete the kept directories when they are empty. |
|
|
40
|
+
| `--location <global\|local\|project>` | Which installation to remove. Global is the default and is resolved the same way as for install. |
|
|
41
|
+
| `--path <dir>` | Remove the installation at exactly this directory. |
|
|
42
|
+
|
|
43
|
+
Flag form and bare verb are equivalent: `--remove` and `remove`, `--force` and `-f`.
|
|
44
|
+
|
|
45
|
+
## What is removed
|
|
46
|
+
|
|
47
|
+
Everything in the installation directory, except the entries listed in the next section:
|
|
48
|
+
|
|
49
|
+
- the engine and runtime: `tools/`, `tools/lib/`
|
|
50
|
+
- metadata: `SKILL.md`, `skill.json`, `package.json`, the manifest JSON files
|
|
51
|
+
- `schemas/`, `refs/`, `templates/`, `docs/`, `tests/`
|
|
52
|
+
- `INDEX.json` and any other generated file in that directory
|
|
53
|
+
|
|
54
|
+
Each removed entry is printed as `Removed file: <name>` or `Removed directory: <name>/`.
|
|
55
|
+
|
|
56
|
+
## What is kept
|
|
57
|
+
|
|
58
|
+
| Kept | Why |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `handoffs/`, `projects/`, `links/` | Your session data. |
|
|
61
|
+
| `handoff.config.json` | Your configuration. |
|
|
62
|
+
| `.env.example` | Your environment template. |
|
|
63
|
+
| Anything you added elsewhere in the directory | The installer only removes entries it walks past; it never deletes a directory it keeps. |
|
|
64
|
+
|
|
65
|
+
With `--force`, the three data directories are still kept unless they are empty, in which case
|
|
66
|
+
they are removed and reported as `Removed empty directory: <name>/`. After that, if the
|
|
67
|
+
installation directory itself is empty it is removed too. If handoffs remain in it, the
|
|
68
|
+
directory stays.
|
|
69
|
+
|
|
70
|
+
## Manual uninstall
|
|
71
|
+
|
|
72
|
+
Remove the skill files and leave the data behind:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
cd "<install-path>"
|
|
76
|
+
|
|
77
|
+
# Keep these: handoffs/ projects/ links/ handoff.config.json .env.example
|
|
78
|
+
rm -rf tools docs refs templates schemas src tests
|
|
79
|
+
rm -f SKILL.md skill.json package.json INDEX.json \
|
|
80
|
+
capability-registry.json permission-policy.json \
|
|
81
|
+
handoff.config.schema.json handoff.config.example.json
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
If you never store handoffs inside the installation — for example when `HANDOFFS_ROOT` points
|
|
85
|
+
somewhere else — and you do not need anything else in it, the whole directory can go:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
rm -rf "<install-path>"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Check where handoff data actually lives before doing that:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
node "<install-path>/tools/handoff.mjs" config
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`handoff: config root=<dir>` is the directory that holds your handoffs.
|
|
98
|
+
|
|
99
|
+
## After uninstalling
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx agents-handoff --list
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The removed location should no longer appear. Handoff data that was kept still exists on disk
|
|
106
|
+
and can be read by a later installation, or by any tool that reads a handoff folder directly.
|
|
107
|
+
|
|
108
|
+
## Troubleshooting
|
|
109
|
+
|
|
110
|
+
| Symptom | Cause and fix |
|
|
111
|
+
|---|---|
|
|
112
|
+
| `Not installed at <dir>` | That location holds no installation. Check `--list` and `where`, then retry with the right `--location` or `--path`. |
|
|
113
|
+
| Nothing was removed | The confirmation was skipped. Pass `--force`. |
|
|
114
|
+
| `EPERM` or `EBUSY` on Windows | A process is holding the files. Close it and retry, or check file attributes. |
|
|
115
|
+
| Permission denied | The installation is outside your user directory. Remove it with the privileges that created it, or use `--force` from a shell that can write there. |
|
|
116
|
+
| Handoff data disappeared | It was an empty kept directory removed by `--force`, or `HANDOFFS_ROOT` points elsewhere. Check the root printed by `handoff.mjs config`. |
|
|
117
|
+
|
|
118
|
+
## See also
|
|
119
|
+
|
|
120
|
+
- [INSTALL.md](INSTALL.md)
|
|
121
|
+
- [UPGRADE.md](UPGRADE.md)
|
|
122
|
+
- [../README.md](https://github.com/Alot1z/agent-handoff/blob/main/README.md)
|
package/docs/UPGRADE.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
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
|
+
`--update` requires an existing installation; without one it exits with
|
|
39
|
+
`Not installed at <dir>. Run 'install' first.`
|
|
40
|
+
|
|
41
|
+
The update then reinstalls: the skill files are copied over the existing installation and
|
|
42
|
+
overwrite the files of the same name. Files that are not part of the installation manifest —
|
|
43
|
+
`handoffs/`, `projects/`, `links/`, `handoff.config.json`, `.env.example`, and anything you added
|
|
44
|
+
— are left in place.
|
|
45
|
+
|
|
46
|
+
To update into a specific location or version:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx agents-handoff --update --location project
|
|
50
|
+
npx agents-handoff --update --version 2.0.0
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`--version` installs the version you ask for: the tree beside the installer when there is one
|
|
54
|
+
(a checkout, a release archive), or the archive of that version's tag when there is not (the
|
|
55
|
+
published package carries the installer alone). Confirm what is actually installed with
|
|
56
|
+
`--verify`, which prints the version read back from the installed `SKILL.md`, rather than
|
|
57
|
+
trusting the request.
|
|
58
|
+
|
|
59
|
+
## Manual upgrade
|
|
60
|
+
|
|
61
|
+
Replace the skill files and keep the data:
|
|
62
|
+
|
|
63
|
+
1. Extract the release archive (`agent-handoff-latest.zip`, or
|
|
64
|
+
`agent-handoff-v<version>.zip`) to a temporary directory.
|
|
65
|
+
2. Copy the skill files over the installation: `SKILL.md`, `skill.json`, the manifest JSON
|
|
66
|
+
files, `tools/`, `tools/lib/`, `schemas/`, `refs/`, `templates/`, `docs/`, `tests/`.
|
|
67
|
+
3. Do not delete `handoffs/`, `projects/`, `links/`, or `handoff.config.json`.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
unzip agent-handoff-latest.zip -d /tmp/agent-handoff-new
|
|
71
|
+
cp -r /tmp/agent-handoff-new/tools/ /tmp/agent-handoff-new/refs/ \
|
|
72
|
+
/tmp/agent-handoff-new/templates/ /tmp/agent-handoff-new/schemas/ \
|
|
73
|
+
/tmp/agent-handoff-new/docs/ "<install-path>/"
|
|
74
|
+
cp /tmp/agent-handoff-new/SKILL.md /tmp/agent-handoff-new/skill.json "<install-path>/"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## What an upgrade changes
|
|
78
|
+
|
|
79
|
+
| Changed | Unchanged |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `tools/` — the engine and the dynamic runtime | `handoffs/` — your session data |
|
|
82
|
+
| `refs/`, `templates/`, `schemas/`, `docs/` | `projects/`, `links/` |
|
|
83
|
+
| `SKILL.md`, `skill.json`, manifest JSON files | `handoff.config.json` and your edits |
|
|
84
|
+
| `install/` — the installer itself | `HANDOFFS_ROOT`, if you use it |
|
|
85
|
+
|
|
86
|
+
Handoff folders are read from the handoff root in place, so an upgrade does not move or rewrite
|
|
87
|
+
them.
|
|
88
|
+
|
|
89
|
+
## After upgrading
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx agents-handoff --verify
|
|
93
|
+
node "<install-path>/tools/handoff.mjs" config
|
|
94
|
+
node "<install-path>/tools/handoff.mjs" list
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`config` proves the engine starts and prints the handoff root it resolved. `list` proves the
|
|
98
|
+
engine still finds the handoff folders that were already there.
|
|
99
|
+
|
|
100
|
+
The shipped test suite is a stronger check and does not touch existing handoffs when you point
|
|
101
|
+
it at a scratch root:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
HANDOFFS_ROOT=/tmp/handoff-check node "<install-path>/tools/handoff.test.mjs"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Read an existing handoff to confirm the data survived:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
node "<install-path>/tools/handoff.mjs" show <id-prefix>
|
|
111
|
+
node "<install-path>/tools/handoff.mjs" verify <id-prefix>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`verify <id-prefix>` recomputes the stored handoff's manifest hash, so it fails loudly if an
|
|
115
|
+
upgrade damaged the folder.
|
|
116
|
+
|
|
117
|
+
## Rollback
|
|
118
|
+
|
|
119
|
+
1. Restore the previous version's skill files: extract that version's release archive and copy
|
|
120
|
+
the skill files over the installation, as in the manual upgrade above.
|
|
121
|
+
2. Or reinstall the files that ship with the installer: `npx agents-handoff --force`.
|
|
122
|
+
3. Restore handoffs from your backup if you made one, and confirm with `--verify` and
|
|
123
|
+
`handoff.mjs list`.
|
|
124
|
+
|
|
125
|
+
## Troubleshooting
|
|
126
|
+
|
|
127
|
+
| Symptom | Cause and fix |
|
|
128
|
+
|---|---|
|
|
129
|
+
| `Not installed at <dir>` | Nothing to update at that location. Check `--list`, or drop `--location`/`--path`. |
|
|
130
|
+
| Reported version did not change | The installer installs the tree beside it when there is one, so running it from a checkout installs that checkout. Use the published package, or pass `--version <x>` to fetch a tagged archive. |
|
|
131
|
+
| Verification fails after an upgrade | A file is missing or the engine cannot start. Reinstall with `--force` and read the failing check. |
|
|
132
|
+
| 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. |
|
|
133
|
+
| Configuration was overwritten | `handoff.config.json` is preserved, but a manual copy step can still overwrite it. Restore your backup. |
|
|
134
|
+
|
|
135
|
+
## See also
|
|
136
|
+
|
|
137
|
+
- [INSTALL.md](INSTALL.md)
|
|
138
|
+
- [UNINSTALL.md](UNINSTALL.md)
|
|
139
|
+
- [../README.md](https://github.com/Alot1z/agent-handoff/blob/main/README.md)
|
package/docs/_config.yml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
title: agent-handoff
|
|
2
|
+
description: Cross-harness capture and verified continuation for AI working sessions.
|
|
3
|
+
url: https://alot1z.github.io
|
|
4
|
+
baseurl: /agent-handoff
|
|
5
|
+
plugins:
|
|
6
|
+
- jekyll-relative-links
|
|
7
|
+
relative_links:
|
|
8
|
+
enabled: true
|
|
9
|
+
collections: false
|
|
10
|
+
defaults:
|
|
11
|
+
- scope:
|
|
12
|
+
path: ""
|
|
13
|
+
values:
|
|
14
|
+
layout: default
|
|
15
|
+
exclude:
|
|
16
|
+
- 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
|
+
}
|