handoff-mcp-server 0.13.1 → 0.15.1
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/Cargo.lock +24 -229
- package/Cargo.toml +1 -1
- package/README.md +55 -0
- package/package.json +1 -1
- package/skills/handoff/SKILL.md +17 -0
- package/skills/handoff-memory/SKILL.md +139 -0
- package/src/cli.rs +551 -0
- package/src/lib.rs +1 -0
- package/src/main.rs +16 -6
- package/src/mcp/handlers/bulk_update.rs +1 -1
- package/src/mcp/handlers/check_criterion.rs +5 -6
- package/src/mcp/handlers/config.rs +38 -0
- package/src/mcp/handlers/get_task.rs +3 -6
- package/src/mcp/handlers/log_time.rs +3 -6
- package/src/mcp/handlers/mod.rs +4 -0
- package/src/mcp/handlers/timer.rs +529 -0
- package/src/mcp/handlers/update_task.rs +10 -21
- package/src/mcp/tools.rs +37 -0
- package/src/storage/config.rs +25 -0
- package/src/storage/tasks.rs +95 -4
package/Cargo.lock
CHANGED
|
@@ -13,9 +13,9 @@ dependencies = [
|
|
|
13
13
|
|
|
14
14
|
[[package]]
|
|
15
15
|
name = "anyhow"
|
|
16
|
-
version = "1.0.
|
|
16
|
+
version = "1.0.103"
|
|
17
17
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
18
|
-
checksum = "
|
|
18
|
+
checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
|
|
19
19
|
|
|
20
20
|
[[package]]
|
|
21
21
|
name = "autocfg"
|
|
@@ -37,9 +37,9 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
|
|
|
37
37
|
|
|
38
38
|
[[package]]
|
|
39
39
|
name = "cc"
|
|
40
|
-
version = "1.2.
|
|
40
|
+
version = "1.2.65"
|
|
41
41
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
42
|
-
checksum = "
|
|
42
|
+
checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
|
|
43
43
|
dependencies = [
|
|
44
44
|
"find-msvc-tools",
|
|
45
45
|
"shlex",
|
|
@@ -99,12 +99,6 @@ version = "0.1.9"
|
|
|
99
99
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
100
100
|
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
|
101
101
|
|
|
102
|
-
[[package]]
|
|
103
|
-
name = "foldhash"
|
|
104
|
-
version = "0.1.5"
|
|
105
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
106
|
-
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
|
107
|
-
|
|
108
102
|
[[package]]
|
|
109
103
|
name = "futures-core"
|
|
110
104
|
version = "0.3.32"
|
|
@@ -131,20 +125,18 @@ dependencies = [
|
|
|
131
125
|
|
|
132
126
|
[[package]]
|
|
133
127
|
name = "getrandom"
|
|
134
|
-
version = "0.4.
|
|
128
|
+
version = "0.4.3"
|
|
135
129
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
136
|
-
checksum = "
|
|
130
|
+
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
|
|
137
131
|
dependencies = [
|
|
138
132
|
"cfg-if",
|
|
139
133
|
"libc",
|
|
140
134
|
"r-efi",
|
|
141
|
-
"wasip2",
|
|
142
|
-
"wasip3",
|
|
143
135
|
]
|
|
144
136
|
|
|
145
137
|
[[package]]
|
|
146
138
|
name = "handoff-mcp"
|
|
147
|
-
version = "0.
|
|
139
|
+
version = "0.15.1"
|
|
148
140
|
dependencies = [
|
|
149
141
|
"anyhow",
|
|
150
142
|
"chrono",
|
|
@@ -157,27 +149,12 @@ dependencies = [
|
|
|
157
149
|
"toml_edit",
|
|
158
150
|
]
|
|
159
151
|
|
|
160
|
-
[[package]]
|
|
161
|
-
name = "hashbrown"
|
|
162
|
-
version = "0.15.5"
|
|
163
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
164
|
-
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
|
165
|
-
dependencies = [
|
|
166
|
-
"foldhash",
|
|
167
|
-
]
|
|
168
|
-
|
|
169
152
|
[[package]]
|
|
170
153
|
name = "hashbrown"
|
|
171
154
|
version = "0.17.1"
|
|
172
155
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
173
156
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
|
174
157
|
|
|
175
|
-
[[package]]
|
|
176
|
-
name = "heck"
|
|
177
|
-
version = "0.5.0"
|
|
178
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
179
|
-
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
180
|
-
|
|
181
158
|
[[package]]
|
|
182
159
|
name = "iana-time-zone"
|
|
183
160
|
version = "0.1.65"
|
|
@@ -202,12 +179,6 @@ dependencies = [
|
|
|
202
179
|
"cc",
|
|
203
180
|
]
|
|
204
181
|
|
|
205
|
-
[[package]]
|
|
206
|
-
name = "id-arena"
|
|
207
|
-
version = "2.3.0"
|
|
208
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
209
|
-
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
|
210
|
-
|
|
211
182
|
[[package]]
|
|
212
183
|
name = "indexmap"
|
|
213
184
|
version = "2.14.0"
|
|
@@ -215,9 +186,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
215
186
|
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
|
216
187
|
dependencies = [
|
|
217
188
|
"equivalent",
|
|
218
|
-
"hashbrown
|
|
219
|
-
"serde",
|
|
220
|
-
"serde_core",
|
|
189
|
+
"hashbrown",
|
|
221
190
|
]
|
|
222
191
|
|
|
223
192
|
[[package]]
|
|
@@ -228,21 +197,15 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|
|
228
197
|
|
|
229
198
|
[[package]]
|
|
230
199
|
name = "js-sys"
|
|
231
|
-
version = "0.3.
|
|
200
|
+
version = "0.3.103"
|
|
232
201
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
233
|
-
checksum = "
|
|
202
|
+
checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
|
|
234
203
|
dependencies = [
|
|
235
204
|
"cfg-if",
|
|
236
205
|
"futures-util",
|
|
237
206
|
"wasm-bindgen",
|
|
238
207
|
]
|
|
239
208
|
|
|
240
|
-
[[package]]
|
|
241
|
-
name = "leb128fmt"
|
|
242
|
-
version = "0.1.0"
|
|
243
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
244
|
-
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
|
245
|
-
|
|
246
209
|
[[package]]
|
|
247
210
|
name = "lexsim"
|
|
248
211
|
version = "0.1.0"
|
|
@@ -267,9 +230,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
|
|
267
230
|
|
|
268
231
|
[[package]]
|
|
269
232
|
name = "log"
|
|
270
|
-
version = "0.4.
|
|
233
|
+
version = "0.4.33"
|
|
271
234
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
272
|
-
checksum = "
|
|
235
|
+
checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
|
|
273
236
|
|
|
274
237
|
[[package]]
|
|
275
238
|
name = "memchr"
|
|
@@ -298,16 +261,6 @@ version = "0.2.17"
|
|
|
298
261
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
299
262
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
|
300
263
|
|
|
301
|
-
[[package]]
|
|
302
|
-
name = "prettyplease"
|
|
303
|
-
version = "0.2.37"
|
|
304
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
305
|
-
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
|
306
|
-
dependencies = [
|
|
307
|
-
"proc-macro2",
|
|
308
|
-
"syn",
|
|
309
|
-
]
|
|
310
|
-
|
|
311
264
|
[[package]]
|
|
312
265
|
name = "proc-macro2"
|
|
313
266
|
version = "1.0.106"
|
|
@@ -319,9 +272,9 @@ dependencies = [
|
|
|
319
272
|
|
|
320
273
|
[[package]]
|
|
321
274
|
name = "quote"
|
|
322
|
-
version = "1.0.
|
|
275
|
+
version = "1.0.46"
|
|
323
276
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
324
|
-
checksum = "
|
|
277
|
+
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
|
|
325
278
|
dependencies = [
|
|
326
279
|
"proc-macro2",
|
|
327
280
|
]
|
|
@@ -351,12 +304,6 @@ version = "1.0.22"
|
|
|
351
304
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
352
305
|
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
|
353
306
|
|
|
354
|
-
[[package]]
|
|
355
|
-
name = "semver"
|
|
356
|
-
version = "1.0.28"
|
|
357
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
358
|
-
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
|
|
359
|
-
|
|
360
307
|
[[package]]
|
|
361
308
|
name = "serde"
|
|
362
309
|
version = "1.0.228"
|
|
@@ -424,9 +371,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
|
|
424
371
|
|
|
425
372
|
[[package]]
|
|
426
373
|
name = "syn"
|
|
427
|
-
version = "2.0.
|
|
374
|
+
version = "2.0.118"
|
|
428
375
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
429
|
-
checksum = "
|
|
376
|
+
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
|
|
430
377
|
dependencies = [
|
|
431
378
|
"proc-macro2",
|
|
432
379
|
"quote",
|
|
@@ -543,35 +490,11 @@ version = "1.13.3"
|
|
|
543
490
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
544
491
|
checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
|
|
545
492
|
|
|
546
|
-
[[package]]
|
|
547
|
-
name = "unicode-xid"
|
|
548
|
-
version = "0.2.6"
|
|
549
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
550
|
-
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
|
551
|
-
|
|
552
|
-
[[package]]
|
|
553
|
-
name = "wasip2"
|
|
554
|
-
version = "1.0.4+wasi-0.2.12"
|
|
555
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
556
|
-
checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
|
|
557
|
-
dependencies = [
|
|
558
|
-
"wit-bindgen 0.57.1",
|
|
559
|
-
]
|
|
560
|
-
|
|
561
|
-
[[package]]
|
|
562
|
-
name = "wasip3"
|
|
563
|
-
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
|
|
564
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
565
|
-
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
|
|
566
|
-
dependencies = [
|
|
567
|
-
"wit-bindgen 0.51.0",
|
|
568
|
-
]
|
|
569
|
-
|
|
570
493
|
[[package]]
|
|
571
494
|
name = "wasm-bindgen"
|
|
572
|
-
version = "0.2.
|
|
495
|
+
version = "0.2.126"
|
|
573
496
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
574
|
-
checksum = "
|
|
497
|
+
checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
|
|
575
498
|
dependencies = [
|
|
576
499
|
"cfg-if",
|
|
577
500
|
"once_cell",
|
|
@@ -582,9 +505,9 @@ dependencies = [
|
|
|
582
505
|
|
|
583
506
|
[[package]]
|
|
584
507
|
name = "wasm-bindgen-macro"
|
|
585
|
-
version = "0.2.
|
|
508
|
+
version = "0.2.126"
|
|
586
509
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
587
|
-
checksum = "
|
|
510
|
+
checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
|
|
588
511
|
dependencies = [
|
|
589
512
|
"quote",
|
|
590
513
|
"wasm-bindgen-macro-support",
|
|
@@ -592,9 +515,9 @@ dependencies = [
|
|
|
592
515
|
|
|
593
516
|
[[package]]
|
|
594
517
|
name = "wasm-bindgen-macro-support"
|
|
595
|
-
version = "0.2.
|
|
518
|
+
version = "0.2.126"
|
|
596
519
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
597
|
-
checksum = "
|
|
520
|
+
checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
|
|
598
521
|
dependencies = [
|
|
599
522
|
"bumpalo",
|
|
600
523
|
"proc-macro2",
|
|
@@ -605,47 +528,13 @@ dependencies = [
|
|
|
605
528
|
|
|
606
529
|
[[package]]
|
|
607
530
|
name = "wasm-bindgen-shared"
|
|
608
|
-
version = "0.2.
|
|
531
|
+
version = "0.2.126"
|
|
609
532
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
610
|
-
checksum = "
|
|
533
|
+
checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
|
|
611
534
|
dependencies = [
|
|
612
535
|
"unicode-ident",
|
|
613
536
|
]
|
|
614
537
|
|
|
615
|
-
[[package]]
|
|
616
|
-
name = "wasm-encoder"
|
|
617
|
-
version = "0.244.0"
|
|
618
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
619
|
-
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
|
|
620
|
-
dependencies = [
|
|
621
|
-
"leb128fmt",
|
|
622
|
-
"wasmparser",
|
|
623
|
-
]
|
|
624
|
-
|
|
625
|
-
[[package]]
|
|
626
|
-
name = "wasm-metadata"
|
|
627
|
-
version = "0.244.0"
|
|
628
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
629
|
-
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
|
|
630
|
-
dependencies = [
|
|
631
|
-
"anyhow",
|
|
632
|
-
"indexmap",
|
|
633
|
-
"wasm-encoder",
|
|
634
|
-
"wasmparser",
|
|
635
|
-
]
|
|
636
|
-
|
|
637
|
-
[[package]]
|
|
638
|
-
name = "wasmparser"
|
|
639
|
-
version = "0.244.0"
|
|
640
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
641
|
-
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
|
|
642
|
-
dependencies = [
|
|
643
|
-
"bitflags",
|
|
644
|
-
"hashbrown 0.15.5",
|
|
645
|
-
"indexmap",
|
|
646
|
-
"semver",
|
|
647
|
-
]
|
|
648
|
-
|
|
649
538
|
[[package]]
|
|
650
539
|
name = "windows-core"
|
|
651
540
|
version = "0.62.2"
|
|
@@ -723,100 +612,6 @@ dependencies = [
|
|
|
723
612
|
"memchr",
|
|
724
613
|
]
|
|
725
614
|
|
|
726
|
-
[[package]]
|
|
727
|
-
name = "wit-bindgen"
|
|
728
|
-
version = "0.51.0"
|
|
729
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
730
|
-
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
|
731
|
-
dependencies = [
|
|
732
|
-
"wit-bindgen-rust-macro",
|
|
733
|
-
]
|
|
734
|
-
|
|
735
|
-
[[package]]
|
|
736
|
-
name = "wit-bindgen"
|
|
737
|
-
version = "0.57.1"
|
|
738
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
739
|
-
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
|
740
|
-
|
|
741
|
-
[[package]]
|
|
742
|
-
name = "wit-bindgen-core"
|
|
743
|
-
version = "0.51.0"
|
|
744
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
745
|
-
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
|
|
746
|
-
dependencies = [
|
|
747
|
-
"anyhow",
|
|
748
|
-
"heck",
|
|
749
|
-
"wit-parser",
|
|
750
|
-
]
|
|
751
|
-
|
|
752
|
-
[[package]]
|
|
753
|
-
name = "wit-bindgen-rust"
|
|
754
|
-
version = "0.51.0"
|
|
755
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
756
|
-
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
|
|
757
|
-
dependencies = [
|
|
758
|
-
"anyhow",
|
|
759
|
-
"heck",
|
|
760
|
-
"indexmap",
|
|
761
|
-
"prettyplease",
|
|
762
|
-
"syn",
|
|
763
|
-
"wasm-metadata",
|
|
764
|
-
"wit-bindgen-core",
|
|
765
|
-
"wit-component",
|
|
766
|
-
]
|
|
767
|
-
|
|
768
|
-
[[package]]
|
|
769
|
-
name = "wit-bindgen-rust-macro"
|
|
770
|
-
version = "0.51.0"
|
|
771
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
772
|
-
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
|
|
773
|
-
dependencies = [
|
|
774
|
-
"anyhow",
|
|
775
|
-
"prettyplease",
|
|
776
|
-
"proc-macro2",
|
|
777
|
-
"quote",
|
|
778
|
-
"syn",
|
|
779
|
-
"wit-bindgen-core",
|
|
780
|
-
"wit-bindgen-rust",
|
|
781
|
-
]
|
|
782
|
-
|
|
783
|
-
[[package]]
|
|
784
|
-
name = "wit-component"
|
|
785
|
-
version = "0.244.0"
|
|
786
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
787
|
-
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
|
|
788
|
-
dependencies = [
|
|
789
|
-
"anyhow",
|
|
790
|
-
"bitflags",
|
|
791
|
-
"indexmap",
|
|
792
|
-
"log",
|
|
793
|
-
"serde",
|
|
794
|
-
"serde_derive",
|
|
795
|
-
"serde_json",
|
|
796
|
-
"wasm-encoder",
|
|
797
|
-
"wasm-metadata",
|
|
798
|
-
"wasmparser",
|
|
799
|
-
"wit-parser",
|
|
800
|
-
]
|
|
801
|
-
|
|
802
|
-
[[package]]
|
|
803
|
-
name = "wit-parser"
|
|
804
|
-
version = "0.244.0"
|
|
805
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
806
|
-
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
|
|
807
|
-
dependencies = [
|
|
808
|
-
"anyhow",
|
|
809
|
-
"id-arena",
|
|
810
|
-
"indexmap",
|
|
811
|
-
"log",
|
|
812
|
-
"semver",
|
|
813
|
-
"serde",
|
|
814
|
-
"serde_derive",
|
|
815
|
-
"serde_json",
|
|
816
|
-
"unicode-xid",
|
|
817
|
-
"wasmparser",
|
|
818
|
-
]
|
|
819
|
-
|
|
820
615
|
[[package]]
|
|
821
616
|
name = "zmij"
|
|
822
617
|
version = "1.0.21"
|
package/Cargo.toml
CHANGED
package/README.md
CHANGED
|
@@ -198,6 +198,14 @@ rename) so a concurrent reader never sees a partially-written file.
|
|
|
198
198
|
| `handoff_get_referral` | Fetch one incoming referral in full — details, suggested tasks, done_criteria, context |
|
|
199
199
|
| `handoff_update_referral` | Update referral status (open → acknowledged → resolved) |
|
|
200
200
|
|
|
201
|
+
### Timer Coordination
|
|
202
|
+
|
|
203
|
+
| Tool | Purpose |
|
|
204
|
+
|------|---------|
|
|
205
|
+
| `handoff_timer_start` | Start tracking time for a task — delegates to VSCode extension if alive, otherwise starts MCP fallback timer |
|
|
206
|
+
| `handoff_timer_stop` | Stop the timer and log elapsed hours to `actual_hours` — delegates to VSCode if alive |
|
|
207
|
+
| `handoff_timer_get_time` | Get current timer state (elapsed, authority, projected total) without stopping |
|
|
208
|
+
|
|
201
209
|
### Project Memory
|
|
202
210
|
|
|
203
211
|
| Tool | Purpose |
|
|
@@ -207,6 +215,7 @@ rename) so a concurrent reader never sees a partially-written file.
|
|
|
207
215
|
| `handoff_memory_delete` | Delete a memory by id (full id or unique prefix) |
|
|
208
216
|
| `handoff_memory_cleanup` | Housekeeping (for SessionStart): silently merge exact duplicates, return near-duplicate/stale recommendations, gc old injection sidecars |
|
|
209
217
|
|
|
218
|
+
For usage best practices (granularity, scope_paths, conflict handling, cleanup), see `skills/handoff-memory/SKILL.md`.
|
|
210
219
|
See [Project Memory](#project-memory-1) below for what it is and how to wire automatic injection.
|
|
211
220
|
|
|
212
221
|
### Task Data Model
|
|
@@ -279,6 +288,9 @@ done_task_limit = 10 # Max completed tasks to show
|
|
|
279
288
|
auto_git_summary = true # Capture git state automatically
|
|
280
289
|
require_estimate_hours = true # Require estimate_hours on leaf tasks (default true)
|
|
281
290
|
ai_estimate_multiplier = 0.2 # Multiplier turning human estimates into AI-effort hours
|
|
291
|
+
timer_provider = "auto" # "auto" | "vscode" | "mcp" | "off"
|
|
292
|
+
timer_authority_ttl_secs = 30 # Heartbeat freshness TTL for authority.json
|
|
293
|
+
timer_idle_timeout_minutes = 10 # Idle pause threshold for MCP fallback timer
|
|
282
294
|
|
|
283
295
|
[dashboard]
|
|
284
296
|
scan_dirs = ["~/pro/"] # Directories to scan for dashboard
|
|
@@ -462,6 +474,45 @@ All under `[settings]` in `.handoff/config.toml`, all with safe defaults
|
|
|
462
474
|
| `memory_stale_days` | `60` | Days without a reference before a memory is flagged stale |
|
|
463
475
|
| `memory_injected_gc_days` | `14` | Age at which per-session injection sidecars are garbage-collected |
|
|
464
476
|
|
|
477
|
+
## CLI API
|
|
478
|
+
|
|
479
|
+
Since v0.15.0, every MCP tool is also callable directly from the shell:
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
handoff-mcp <group> <action> [--key value ...]
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
All output is JSON on stdout, suitable for scripting and programmatic use
|
|
486
|
+
(e.g. `child_process.execFile` from a VSCode extension).
|
|
487
|
+
|
|
488
|
+
**Examples:**
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
# Memory operations
|
|
492
|
+
handoff-mcp memory save --text "Always use atomic_write" --kind lesson --tags safety,io
|
|
493
|
+
handoff-mcp memory query --text "atomic" --limit 5
|
|
494
|
+
handoff-mcp memory delete --id m-20260630-...
|
|
495
|
+
|
|
496
|
+
# Task management
|
|
497
|
+
handoff-mcp task list --status-filter todo
|
|
498
|
+
handoff-mcp task update --id t1 --title "New task" --status todo --estimate-hours 2
|
|
499
|
+
handoff-mcp task log-time --task-id t1 --hours 0.5
|
|
500
|
+
|
|
501
|
+
# Session and metrics
|
|
502
|
+
handoff-mcp session load
|
|
503
|
+
handoff-mcp metrics
|
|
504
|
+
handoff-mcp dashboard
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
**Available groups:** `init`, `task`, `session`, `config`, `memory`,
|
|
508
|
+
`referral`, `assignee`, `milestone`, `calendar`, `labels`, `project`,
|
|
509
|
+
`metrics`, `capacity`, `schedule`, `dashboard`, `timer`.
|
|
510
|
+
|
|
511
|
+
Run `handoff-mcp --help` to see all groups, or `handoff-mcp <group> --help`
|
|
512
|
+
for actions within a group. See the
|
|
513
|
+
[CLI API Reference](https://github.com/alphaelements/handoff-mcp/wiki/CLI-API-Reference)
|
|
514
|
+
on the wiki for the full command list.
|
|
515
|
+
|
|
465
516
|
## MCP Resources
|
|
466
517
|
|
|
467
518
|
| URI | Description |
|
|
@@ -489,6 +540,10 @@ This project uses handoff-mcp for session continuity.
|
|
|
489
540
|
- **Decisions**: Record decisions with confidence levels as they are made,
|
|
490
541
|
not just at session end. Use `confirmed` for verified facts, `estimated`
|
|
491
542
|
for reasonable assumptions, `unverified` for unknowns.
|
|
543
|
+
- **Timer**: Use `handoff_timer_start` / `handoff_timer_stop` to track task time.
|
|
544
|
+
When the VSCode extension is running, the timer delegates to it automatically.
|
|
545
|
+
When the extension is absent, MCP runs a fallback timer and logs hours on stop.
|
|
546
|
+
Use `handoff_timer_get_time` to check elapsed time without stopping.
|
|
492
547
|
- **Project memory**: Use `handoff_memory_save` to record durable lessons, rules,
|
|
493
548
|
conventions, and gotchas that every future session should know. Use
|
|
494
549
|
`handoff_memory_query` to retrieve relevant memories. Near-duplicate memories are
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "handoff-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "MCP server that gives AI coding agents persistent memory across sessions",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "AlphaElements <66808803+alphaelements@users.noreply.github.com>",
|
package/skills/handoff/SKILL.md
CHANGED
|
@@ -105,6 +105,23 @@ Use `handoff_log_time` to record hours worked on a task:
|
|
|
105
105
|
`schedule: { milestone: "v2" }` updates only the milestone and preserves
|
|
106
106
|
`actual_hours`/`remaining_hours`. It never replaces the whole schedule object.
|
|
107
107
|
|
|
108
|
+
### Timer Coordination (MCP ⇄ VSCode)
|
|
109
|
+
|
|
110
|
+
Use `handoff_timer_start` / `handoff_timer_stop` / `handoff_timer_get_time` to
|
|
111
|
+
track task time with automatic VSCode extension coordination:
|
|
112
|
+
|
|
113
|
+
- **`handoff_timer_start`** — if the VSCode extension is running (live authority
|
|
114
|
+
heartbeat), the request is delegated via `.handoff/timer/requests/`. If absent,
|
|
115
|
+
MCP starts a fallback internal timer.
|
|
116
|
+
- **`handoff_timer_stop`** — if delegated, creates a stop request for the extension.
|
|
117
|
+
If MCP is the fallback, stops the timer and atomically logs elapsed hours to
|
|
118
|
+
`actual_hours` (same as `handoff_log_time`).
|
|
119
|
+
- **`handoff_timer_get_time`** — reads `.handoff/timer/state.json` to show
|
|
120
|
+
elapsed time, state (tracking/paused/stopped), and current authority (vscode/mcp).
|
|
121
|
+
- The `timer_provider` config setting controls behavior: `"auto"` (default) uses
|
|
122
|
+
the authority protocol, `"vscode"` always delegates, `"mcp"` always uses
|
|
123
|
+
fallback, `"off"` disables timer tools entirely.
|
|
124
|
+
|
|
108
125
|
### Metrics & Project Health
|
|
109
126
|
|
|
110
127
|
Check project health with `handoff_get_metrics` at session start:
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: handoff-memory
|
|
3
|
+
description: "Project memory — save, query, merge, and clean up durable project knowledge (lessons, rules, conventions, gotchas). Triggers on 'メモリ保存', 'これ覚えて', '知見を残して', '過去の知見', 'memory save', 'memory query', 'remember this', 'recall', 'cleanup memories', or when recording post-incident learnings, recurring NG patterns, or project-specific conventions."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Handoff Memory Skill
|
|
7
|
+
|
|
8
|
+
## When to use
|
|
9
|
+
|
|
10
|
+
- The user says "メモリ保存", "これ覚えて", "知見を残して", "remember this", "save this as a memory"
|
|
11
|
+
- The user asks "過去の知見を確認", "recall", "what do we know about X"
|
|
12
|
+
- You discover a reusable lesson, recurring NG pattern, or project-specific convention worth persisting across sessions
|
|
13
|
+
- Post-incident feedback or investigation results should be captured
|
|
14
|
+
- Existing memories need merging, updating, or pruning
|
|
15
|
+
- Session start — run cleanup to keep the memory store healthy
|
|
16
|
+
|
|
17
|
+
## Granularity Rule
|
|
18
|
+
|
|
19
|
+
**One memory = one piece of knowledge.** Do not bundle multiple unrelated lessons
|
|
20
|
+
into a single memory. Each memory should be independently searchable and
|
|
21
|
+
independently deletable. If two ideas always travel together, save them together;
|
|
22
|
+
if they could be relevant in different contexts, split them.
|
|
23
|
+
|
|
24
|
+
## Saving a Memory
|
|
25
|
+
|
|
26
|
+
Call `handoff_memory_save` with:
|
|
27
|
+
|
|
28
|
+
| Param | Required | Description |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `text` | yes | The memory content. Be specific and actionable — "always use X because Y", not "X is important" |
|
|
31
|
+
| `kind` | no (default: `lesson`) | One of: `lesson` (something learned), `rule` (a mandated practice), `convention` (an agreed pattern), `gotcha` (a non-obvious trap) |
|
|
32
|
+
| `scope_paths` | no | Path prefixes this memory applies to (e.g. `["src/storage/", "src/mcp/handlers/"]`). Memories with matching scope_paths get a relevance boost when the user edits files under those paths |
|
|
33
|
+
| `tags` | no | Free-form tags for searchability (e.g. `["atomic-write", "config"]`). Tags are included in the similarity index |
|
|
34
|
+
| `force` | no | `true` to skip near-duplicate detection and save unconditionally |
|
|
35
|
+
| `merge_into` | no | ID of an existing memory to overwrite with merged content (see Merging below) |
|
|
36
|
+
| `absorb_ids` | no | IDs of memories to delete after merging into the target |
|
|
37
|
+
|
|
38
|
+
### scope_paths Best Practices
|
|
39
|
+
|
|
40
|
+
- Use directory-level substrings, not full file paths: `"src/storage/"` not `"src/storage/config.rs"`. The matching is substring-based (`file_path.contains(scope)`), so `"storage/"` will match any file whose path contains that segment
|
|
41
|
+
- Scope broadly enough to catch related files, narrowly enough to avoid noise
|
|
42
|
+
- A memory with no scope_paths relies purely on text similarity for injection — fine for project-wide rules, but file-specific gotchas benefit from scoping
|
|
43
|
+
|
|
44
|
+
### tags Best Practices
|
|
45
|
+
|
|
46
|
+
- Use lowercase, hyphenated terms: `"atomic-write"`, `"json-rpc"`, `"config-toml"`
|
|
47
|
+
- Tags supplement the body text for search — add tags for synonyms or concepts not explicitly mentioned in the body
|
|
48
|
+
|
|
49
|
+
## Handling Near-Duplicate Conflicts
|
|
50
|
+
|
|
51
|
+
When `handoff_memory_save` returns `status: "conflict"`, it means the new memory
|
|
52
|
+
is similar to one or more existing memories (Jaccard similarity >= threshold). The
|
|
53
|
+
response includes both the new text and the similar existing memories.
|
|
54
|
+
|
|
55
|
+
**Decision flow:**
|
|
56
|
+
|
|
57
|
+
1. **Read both texts carefully.** Are they expressing the same knowledge?
|
|
58
|
+
2. **If yes — merge:** Write a combined text that captures both perspectives, then call `handoff_memory_save` again with:
|
|
59
|
+
- `text`: the merged content
|
|
60
|
+
- `merge_into`: ID of the existing memory to keep
|
|
61
|
+
- `absorb_ids`: IDs of any other similar memories to absorb
|
|
62
|
+
- Update `kind`, `tags`, `scope_paths` as needed
|
|
63
|
+
3. **If no — force-save:** The memories are genuinely distinct despite textual similarity. Call `handoff_memory_save` with `force: true` to save the new one separately.
|
|
64
|
+
|
|
65
|
+
Do not ignore conflicts — they indicate the memory store may have redundancy that degrades injection quality.
|
|
66
|
+
|
|
67
|
+
## Querying Memories
|
|
68
|
+
|
|
69
|
+
Call `handoff_memory_query` with:
|
|
70
|
+
|
|
71
|
+
| Param | Description |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `text` | The prompt or question to match against (BM25 relevance ranking) |
|
|
74
|
+
| `file_paths` | Files being worked on — memories scoped to these paths get a boost |
|
|
75
|
+
| `session_id` | Current session ID — suppresses re-injection of memories already seen this session |
|
|
76
|
+
| `limit` | Max memories to return (default from config, typically 5) |
|
|
77
|
+
| `tool_name` | Tool being used (adds context tokens for matching) |
|
|
78
|
+
| `mark_injected` | Whether to record injection for dedup (default: true) |
|
|
79
|
+
|
|
80
|
+
The query engine uses BM25 text similarity plus a scope_path bonus. Passing
|
|
81
|
+
`session_id` enables per-session diff injection: a memory already injected this
|
|
82
|
+
session (same content hash) is filtered out, but an edited memory (new hash) is
|
|
83
|
+
re-injected.
|
|
84
|
+
|
|
85
|
+
## Cleanup
|
|
86
|
+
|
|
87
|
+
### When to Run
|
|
88
|
+
|
|
89
|
+
Run `handoff_memory_cleanup` at the start of each session (the SessionStart hook
|
|
90
|
+
does this automatically if configured). Optional arguments:
|
|
91
|
+
|
|
92
|
+
| Param | Default | Description |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| `apply_exact_merges` | `true` | Set `false` to skip auto-merging and only return recommendations |
|
|
95
|
+
| `stale_days` | from config (default 60) | Override the staleness threshold in days |
|
|
96
|
+
|
|
97
|
+
It performs three passes:
|
|
98
|
+
|
|
99
|
+
1. **Exact duplicates** — silently auto-merged (lossless; oldest entry kept, others absorbed). Skipped when `apply_exact_merges` is `false`
|
|
100
|
+
2. **Near-duplicate clusters** — returned as recommendations for AI-driven merge
|
|
101
|
+
3. **Stale memories** — memories not referenced for `stale_days`, returned as recommendations
|
|
102
|
+
|
|
103
|
+
### Acting on Cleanup Recommendations
|
|
104
|
+
|
|
105
|
+
- **similar_clusters**: Review each cluster. If the memories are truly redundant, merge them with `handoff_memory_save(merge_into=..., absorb_ids=[...])`. If distinct, leave them.
|
|
106
|
+
- **stale**: Consider whether the memory is obsolete (delete with `handoff_memory_delete`) or simply rarely triggered (leave it — low hit_count doesn't mean low value).
|
|
107
|
+
|
|
108
|
+
### Manual Deletion
|
|
109
|
+
|
|
110
|
+
Call `handoff_memory_delete` with the memory `id` (full ID or unique prefix). Use
|
|
111
|
+
this for memories that are confirmed obsolete, wrong, or superseded by a code
|
|
112
|
+
change.
|
|
113
|
+
|
|
114
|
+
## Memory Hooks (Optional Auto-Injection)
|
|
115
|
+
|
|
116
|
+
Memory tools can be called manually, but for automatic injection without AI
|
|
117
|
+
initiative, configure Claude Code hooks:
|
|
118
|
+
|
|
119
|
+
| Hook | Tool Call | Purpose |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `UserPromptSubmit` | `handoff_memory_query` (prompt text) | Inject memories relevant to each user prompt |
|
|
122
|
+
| `PreToolUse` (`Edit\|Write\|MultiEdit`) | `handoff_memory_query` (file path) | Inject memories scoped to the file being edited |
|
|
123
|
+
| `SessionStart` | `handoff_memory_cleanup` | Auto-merge exact duplicates, surface recommendations |
|
|
124
|
+
|
|
125
|
+
Run `handoff-mcp setup` to install these hooks automatically, or
|
|
126
|
+
`handoff-mcp setup --uninstall` to remove them. See the README for the full hook
|
|
127
|
+
JSON configuration.
|
|
128
|
+
|
|
129
|
+
## Memory vs Session vs CLAUDE.md
|
|
130
|
+
|
|
131
|
+
| Layer | Lifespan | Purpose |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| Sessions (`.handoff/sessions/`) | Per-conversation | "What was I doing last time?" |
|
|
134
|
+
| Memory (`.handoff/memory/`) | Cross-session, long-lived | "What has this project learned?" |
|
|
135
|
+
| `CLAUDE.md` | Permanent | Foundational rules, build commands, repo structure |
|
|
136
|
+
| `.claude/skills/` | Permanent | Operational procedures triggered by intent |
|
|
137
|
+
|
|
138
|
+
Rule changes: discover via memory → codify in skills/CLAUDE.md. Memory is the
|
|
139
|
+
source of evidence; skills and CLAUDE.md are the source of authority.
|