threadnote 0.6.0 → 0.6.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/README.md +5 -1
- package/dist/mcp_server.cjs +246 -95
- package/dist/threadnote.cjs +328 -155
- package/docs/agent-instructions.md +8 -0
- package/docs/index.html +185 -106
- package/package.json +1 -1
|
@@ -21,9 +21,17 @@ At the start of a non-trivial task, recall relevant context before making change
|
|
|
21
21
|
- the current repo and branch;
|
|
22
22
|
- recent handoffs;
|
|
23
23
|
- durable feature memories for the branch, feature name, project/topic, or issue;
|
|
24
|
+
- seeded project guidance under `viking://resources/repos/<project>` — README, AGENTS.md, CLAUDE.md, SKILL.md, docs/\*\*
|
|
25
|
+
— for canonical conventions, test commands, release process, on-call runbooks, and anything the team has checked into
|
|
26
|
+
the repo;
|
|
24
27
|
- task-specific skills or workflow guidance;
|
|
25
28
|
- user or team preferences that may affect the work.
|
|
26
29
|
|
|
30
|
+
Include the repo or project name as a token in the recall query so the project-guidance pass fires. `recall_context`
|
|
31
|
+
runs a parallel scoped search against `viking://resources/repos/<project>` whenever the query mentions a seeded project
|
|
32
|
+
name, so memories AND project documentation come back in the same response. Treat seeded resources as the canonical
|
|
33
|
+
source for "how does this repo do X" and personal memories as in-flight or per-author context layered on top.
|
|
34
|
+
|
|
27
35
|
When a recalled handoff describes an active branch or feature, do a second recall for durable memories about that
|
|
28
36
|
feature before coding. The handoff tells you the current work state; durable feature memories tell you the design,
|
|
29
37
|
decisions, invariants, interfaces, and gotchas that should survive beyond one session.
|
package/docs/index.html
CHANGED
|
@@ -78,7 +78,11 @@
|
|
|
78
78
|
body {
|
|
79
79
|
line-height: 1.55;
|
|
80
80
|
font-size: clamp(15px, 1.05vw, 17px);
|
|
81
|
-
overflow-x:
|
|
81
|
+
overflow-x: clip;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
html {
|
|
85
|
+
overflow-x: clip;
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
::selection {
|
|
@@ -117,6 +121,10 @@
|
|
|
117
121
|
padding: 1em 1.2em;
|
|
118
122
|
overflow-x: auto;
|
|
119
123
|
line-height: 1.55;
|
|
124
|
+
/* Without this, a single long unbreakable line (curl URLs, etc.)
|
|
125
|
+
pushes the pre wider than its container and out of the viewport on
|
|
126
|
+
mobile. With it, the pre scrolls internally instead. */
|
|
127
|
+
max-width: 100%;
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
pre code {
|
|
@@ -148,6 +156,10 @@
|
|
|
148
156
|
display: flex;
|
|
149
157
|
flex-direction: column;
|
|
150
158
|
justify-content: center;
|
|
159
|
+
/* Default flex/block intrinsic min-width is the widest child, which
|
|
160
|
+
lets long unbreakable mono lines (URLs, MCP calls) make the inner
|
|
161
|
+
wider than its declared 100%. Hard-cap it. */
|
|
162
|
+
min-width: 0;
|
|
151
163
|
}
|
|
152
164
|
|
|
153
165
|
.slide-eyebrow {
|
|
@@ -222,29 +234,14 @@
|
|
|
222
234
|
align-items: flex-start;
|
|
223
235
|
}
|
|
224
236
|
|
|
225
|
-
.
|
|
226
|
-
position: fixed;
|
|
227
|
-
top: 1.5rem;
|
|
228
|
-
left: 1.5rem;
|
|
229
|
-
width: 220px;
|
|
230
|
-
height: 220px;
|
|
231
|
-
z-index: 40;
|
|
232
|
-
pointer-events: none;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
.page-logo img {
|
|
236
|
-
width: 100%;
|
|
237
|
-
height: 100%;
|
|
237
|
+
.hero-logo {
|
|
238
238
|
display: block;
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
.
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
top: 1rem;
|
|
246
|
-
left: 1rem;
|
|
247
|
-
}
|
|
239
|
+
width: clamp(140px, 18vw, 220px);
|
|
240
|
+
height: auto;
|
|
241
|
+
margin-bottom: 1.5rem;
|
|
242
|
+
/* Override `#hero .slide-inner { align-items: flex-start }` for just
|
|
243
|
+
this child so the logo sits centered above the left-aligned title. */
|
|
244
|
+
align-self: center;
|
|
248
245
|
}
|
|
249
246
|
|
|
250
247
|
.hero-title-gradient {
|
|
@@ -504,35 +501,89 @@
|
|
|
504
501
|
border-radius: var(--radius-lg);
|
|
505
502
|
padding: 1.5rem;
|
|
506
503
|
display: grid;
|
|
507
|
-
gap: 0.
|
|
504
|
+
gap: 0.75rem;
|
|
508
505
|
transition: border-color 0.2s ease;
|
|
506
|
+
/* Let the grid track shrink to its container width rather than to the
|
|
507
|
+
widest mono child. Without this, long MCP call/response lines push
|
|
508
|
+
the grid item past viewport and the page scrolls horizontally on
|
|
509
|
+
mobile. */
|
|
510
|
+
min-width: 0;
|
|
509
511
|
}
|
|
510
512
|
|
|
511
513
|
.vignette:hover {
|
|
512
514
|
border-color: var(--accent-line);
|
|
513
515
|
}
|
|
514
516
|
|
|
515
|
-
.vignette .v-
|
|
517
|
+
.vignette .v-say {
|
|
516
518
|
font-style: italic;
|
|
519
|
+
font-size: 0.96rem;
|
|
517
520
|
color: var(--text);
|
|
518
|
-
|
|
521
|
+
background: rgba(255, 255, 255, 0.03);
|
|
522
|
+
border-left: 3px solid var(--accent);
|
|
523
|
+
border-radius: 4px;
|
|
524
|
+
padding: 0.55rem 0.85rem;
|
|
519
525
|
}
|
|
520
526
|
|
|
521
|
-
.vignette .v-
|
|
527
|
+
.vignette .v-auto {
|
|
528
|
+
font-style: italic;
|
|
522
529
|
color: var(--muted);
|
|
523
|
-
font-size: 0.95rem;
|
|
524
530
|
}
|
|
525
531
|
|
|
526
|
-
.vignette .v-
|
|
532
|
+
.vignette pre.v-call,
|
|
533
|
+
.vignette pre.v-response {
|
|
527
534
|
font-family: var(--font-mono);
|
|
528
|
-
font-size: 0.
|
|
529
|
-
color: var(--accent);
|
|
530
|
-
padding: 0.45rem 0.75rem;
|
|
535
|
+
font-size: 0.78rem;
|
|
531
536
|
background: var(--code-bg);
|
|
537
|
+
padding: 0.55rem 0.75rem;
|
|
532
538
|
border-radius: 6px;
|
|
533
539
|
border: 1px solid var(--line);
|
|
534
|
-
|
|
540
|
+
border-left: 1px solid var(--line);
|
|
541
|
+
white-space: pre-wrap;
|
|
542
|
+
word-break: break-word;
|
|
535
543
|
overflow-x: auto;
|
|
544
|
+
max-width: 100%;
|
|
545
|
+
line-height: 1.45;
|
|
546
|
+
margin: 0;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
.vignette .v-call {
|
|
550
|
+
color: var(--accent);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
.vignette .v-response {
|
|
554
|
+
color: var(--muted);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
.vignette .v-say::before,
|
|
558
|
+
.vignette .v-call::before,
|
|
559
|
+
.vignette .v-response::before {
|
|
560
|
+
display: block;
|
|
561
|
+
font-family: var(--font-mono);
|
|
562
|
+
font-size: 0.68rem;
|
|
563
|
+
letter-spacing: 0.12em;
|
|
564
|
+
text-transform: uppercase;
|
|
565
|
+
color: var(--muted);
|
|
566
|
+
font-style: normal;
|
|
567
|
+
margin-bottom: 0.35rem;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
.vignette .v-say::before {
|
|
571
|
+
content: 'You ask';
|
|
572
|
+
color: var(--accent);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.vignette .v-call::before {
|
|
576
|
+
content: 'Agent calls';
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.vignette .v-response::before {
|
|
580
|
+
content: 'MCP returns';
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.vignette .v-answer {
|
|
584
|
+
color: var(--muted);
|
|
585
|
+
font-size: 0.95rem;
|
|
586
|
+
margin-top: 0.25rem;
|
|
536
587
|
}
|
|
537
588
|
|
|
538
589
|
/* side nav dots */
|
|
@@ -695,10 +746,6 @@
|
|
|
695
746
|
<body>
|
|
696
747
|
<div class="progress"><div class="progress-bar" id="progressBar"></div></div>
|
|
697
748
|
|
|
698
|
-
<div class="page-logo" aria-hidden="true">
|
|
699
|
-
<img src="threadnote-logo-inverted.svg" alt="" />
|
|
700
|
-
</div>
|
|
701
|
-
|
|
702
749
|
<nav class="deck-nav" aria-label="Section progress">
|
|
703
750
|
<a href="#hero" data-label="Intro"><span>Intro</span></a>
|
|
704
751
|
<a href="#problem" data-label="Problem"><span>Problem</span></a>
|
|
@@ -710,8 +757,8 @@
|
|
|
710
757
|
<a href="#seed" data-label="Seed"><span>Seed</span></a>
|
|
711
758
|
<a href="#update" data-label="Update"><span>Update</span></a>
|
|
712
759
|
<a href="#lifecycle" data-label="Lifecycle"><span>Lifecycle</span></a>
|
|
713
|
-
<a href="#use-cases" data-label="Use cases"><span>Use cases</span></a>
|
|
714
760
|
<a href="#share" data-label="Share"><span>Share</span></a>
|
|
761
|
+
<a href="#use-cases" data-label="Use cases"><span>Use cases</span></a>
|
|
715
762
|
<a href="#close" data-label="Get started"><span>Start</span></a>
|
|
716
763
|
</nav>
|
|
717
764
|
|
|
@@ -719,6 +766,7 @@
|
|
|
719
766
|
<!-- 1. HERO -->
|
|
720
767
|
<section id="hero" class="slide">
|
|
721
768
|
<div class="slide-inner">
|
|
769
|
+
<img class="hero-logo" src="threadnote-logo-inverted.svg" alt="" aria-hidden="true" />
|
|
722
770
|
<h1 class="hero-title-gradient">
|
|
723
771
|
Shared local context<br />for <em class="hero-accent">development agents</em>.
|
|
724
772
|
</h1>
|
|
@@ -727,7 +775,7 @@
|
|
|
727
775
|
team-shared decisions — recallable from any session, on any agent, in any worktree.
|
|
728
776
|
</p>
|
|
729
777
|
<div class="cta-row">
|
|
730
|
-
<span class="pill">v0.
|
|
778
|
+
<span class="pill"><span id="version-tag">v0.6.1</span> · local-first · MIT</span>
|
|
731
779
|
</div>
|
|
732
780
|
</div>
|
|
733
781
|
<div class="scroll-cue">scroll ↓ · <span class="kbd">↓</span> / <span class="kbd">j</span></div>
|
|
@@ -1254,75 +1302,10 @@ threadnote remember \
|
|
|
1254
1302
|
</div>
|
|
1255
1303
|
</section>
|
|
1256
1304
|
|
|
1257
|
-
<!-- 11.
|
|
1258
|
-
<section id="use-cases" class="slide">
|
|
1259
|
-
<div class="slide-inner">
|
|
1260
|
-
<span class="slide-eyebrow">10 · Real-world use cases</span>
|
|
1261
|
-
<h2>Where it actually pays off.</h2>
|
|
1262
|
-
|
|
1263
|
-
<div class="vignettes">
|
|
1264
|
-
<div class="vignette reveal">
|
|
1265
|
-
<div class="v-prompt">"Continue the feature from yesterday."</div>
|
|
1266
|
-
<div class="v-answer">
|
|
1267
|
-
Fresh session, fresh agent. Threadnote recalls the active handoff for the branch plus the durable
|
|
1268
|
-
feature memory: design decisions, the open PR, what's left, what just failed in CI. No re-explaining.
|
|
1269
|
-
</div>
|
|
1270
|
-
<div class="v-cmd">threadnote recall --query "<branch> latest handoff"</div>
|
|
1271
|
-
</div>
|
|
1272
|
-
|
|
1273
|
-
<div class="vignette reveal">
|
|
1274
|
-
<div class="v-prompt">"What did we conclude about that prod-on-call thing?"</div>
|
|
1275
|
-
<div class="v-answer">
|
|
1276
|
-
The sanitized handoff from the on-call escalation is still there. Re-open the same Slack thread three
|
|
1277
|
-
weeks later; the durable feature memory points your agent at the right files and the resolution.
|
|
1278
|
-
</div>
|
|
1279
|
-
<div class="v-cmd">threadnote recall --query "export workflow timeout on-call findings"</div>
|
|
1280
|
-
</div>
|
|
1281
|
-
|
|
1282
|
-
<div class="vignette reveal">
|
|
1283
|
-
<div class="v-prompt">"Switch from Codex to Claude mid-task."</div>
|
|
1284
|
-
<div class="v-answer">
|
|
1285
|
-
Codex stores a handoff before pausing. Claude opens the same MCP layer, recalls the handoff plus the
|
|
1286
|
-
durable memory, picks up the test command and the open blocker without you typing them again.
|
|
1287
|
-
</div>
|
|
1288
|
-
<div class="v-cmd">threadnote handoff --task "..." --next-step "..."</div>
|
|
1289
|
-
</div>
|
|
1290
|
-
|
|
1291
|
-
<div class="vignette reveal">
|
|
1292
|
-
<div class="v-prompt">"Onboard a new teammate to a feature."</div>
|
|
1293
|
-
<div class="v-answer">
|
|
1294
|
-
Publish the feature's durable memory to the team repo with <code>share publish</code>. Their agent
|
|
1295
|
-
pulls it on the next <code>share sync</code> and recall surfaces it alongside their own personal
|
|
1296
|
-
memories — no DM forwarding, no PDF dumping.
|
|
1297
|
-
</div>
|
|
1298
|
-
<div class="v-cmd">threadnote share publish viking://user/<you>/memories/durable/...</div>
|
|
1299
|
-
</div>
|
|
1300
|
-
|
|
1301
|
-
<div class="vignette reveal">
|
|
1302
|
-
<div class="v-prompt">"Compaction is about to nuke the context."</div>
|
|
1303
|
-
<div class="v-answer">
|
|
1304
|
-
Before context fills up, the agent stores a handoff. The next turn after compaction recalls it — the
|
|
1305
|
-
summary covers the conversation arc, threadnote covers the durable facts the summary couldn't keep.
|
|
1306
|
-
</div>
|
|
1307
|
-
<div class="v-cmd">threadnote handoff --project <repo> --topic <feature> ...</div>
|
|
1308
|
-
</div>
|
|
1309
|
-
|
|
1310
|
-
<div class="vignette reveal">
|
|
1311
|
-
<div class="v-prompt">"Where does this repo run its release notes?"</div>
|
|
1312
|
-
<div class="v-answer">
|
|
1313
|
-
You discovered it the hard way last time. Tell your agent to <code>remember</code> the fact. Next time
|
|
1314
|
-
anyone asks, the agent finds it in two seconds without grepping the wiki.
|
|
1315
|
-
</div>
|
|
1316
|
-
<div class="v-cmd">threadnote remember --kind durable --topic release-process ...</div>
|
|
1317
|
-
</div>
|
|
1318
|
-
</div>
|
|
1319
|
-
</div>
|
|
1320
|
-
</section>
|
|
1321
|
-
|
|
1322
|
-
<!-- 12. SHARE -->
|
|
1305
|
+
<!-- 11. SHARE -->
|
|
1323
1306
|
<section id="share" class="slide">
|
|
1324
1307
|
<div class="slide-inner">
|
|
1325
|
-
<span class="slide-eyebrow">
|
|
1308
|
+
<span class="slide-eyebrow">10 · Sharing across the team</span>
|
|
1326
1309
|
<h2>Curated memories. Yours to push. Theirs to pull.</h2>
|
|
1327
1310
|
<p class="lead">
|
|
1328
1311
|
<code>threadnote share</code> publishes a subset of durable memories into a git repo so other engineers'
|
|
@@ -1409,6 +1392,81 @@ threadnote remember \
|
|
|
1409
1392
|
</div>
|
|
1410
1393
|
</section>
|
|
1411
1394
|
|
|
1395
|
+
<!-- 12. USE CASES -->
|
|
1396
|
+
<section id="use-cases" class="slide">
|
|
1397
|
+
<div class="slide-inner">
|
|
1398
|
+
<span class="slide-eyebrow">11 · Real-world use cases</span>
|
|
1399
|
+
<h2>What you say. What the agent does.</h2>
|
|
1400
|
+
<p class="lead">
|
|
1401
|
+
You don't run threadnote commands yourself. You talk to your agent the way you already do; the agent calls
|
|
1402
|
+
the MCP layer and the memory stays in sync across sessions, agents, and teammates.
|
|
1403
|
+
</p>
|
|
1404
|
+
|
|
1405
|
+
<div class="vignettes">
|
|
1406
|
+
<div class="vignette reveal">
|
|
1407
|
+
<div class="v-say">Continue where we left off on this branch.</div>
|
|
1408
|
+
<pre class="v-call">recall_context({query: "<branch> latest handoff durable feature memory"})</pre>
|
|
1409
|
+
<pre class="v-response">→ viking://user/you/memories/handoffs/active/<branch>/auto-precompact.md
|
|
1410
|
+
→ viking://user/you/memories/durable/projects/<repo>/<feature>.md</pre>
|
|
1411
|
+
<div class="v-answer">
|
|
1412
|
+
Fresh session, fresh agent. It reads both pointers, picks up the design decisions, the open PR, what's
|
|
1413
|
+
left to test, and what just failed in CI. No re-explaining.
|
|
1414
|
+
</div>
|
|
1415
|
+
</div>
|
|
1416
|
+
|
|
1417
|
+
<div class="vignette reveal">
|
|
1418
|
+
<div class="v-say">Save where we are — I'm switching to another agent.</div>
|
|
1419
|
+
<pre class="v-call">remember_context({kind: "handoff", project: "<repo>", topic: "<feature>", text: "..."})</pre>
|
|
1420
|
+
<pre class="v-response">Stored: viking://user/you/memories/handoffs/active/<repo>/<feature>.md</pre>
|
|
1421
|
+
<div class="v-answer">
|
|
1422
|
+
Open the next agent — the SessionStart hook recalls the same handoff and the durable memory. It picks
|
|
1423
|
+
up the test command and the open blocker without you retyping them.
|
|
1424
|
+
</div>
|
|
1425
|
+
</div>
|
|
1426
|
+
|
|
1427
|
+
<div class="vignette reveal">
|
|
1428
|
+
<div class="v-say">Share this feature's design memory with the team.</div>
|
|
1429
|
+
<pre class="v-call">share_publish({uri: "viking://user/you/memories/durable/projects/<repo>/<feature>.md"})</pre>
|
|
1430
|
+
<pre class="v-response">Published → shared/<team>/durable/projects/<repo>/<feature>.md
|
|
1431
|
+
git push: ok</pre>
|
|
1432
|
+
<div class="v-answer">
|
|
1433
|
+
The memory lands in the team git repo. A teammate's next <code>share sync</code> pulls it; their
|
|
1434
|
+
recall surfaces it alongside their own memories — no DM forwarding, no PDF dumping.
|
|
1435
|
+
</div>
|
|
1436
|
+
</div>
|
|
1437
|
+
|
|
1438
|
+
<div class="vignette reveal">
|
|
1439
|
+
<div class="v-say v-auto">(automatic — the PreCompact hook fires before context compaction)</div>
|
|
1440
|
+
<pre class="v-call">remember_context({kind: "handoff", project: "<repo>", topic: "auto-precompact", text: "..."})</pre>
|
|
1441
|
+
<pre class="v-response">Stored: viking://user/you/memories/handoffs/active/<repo>/auto-precompact.md</pre>
|
|
1442
|
+
<div class="v-answer">
|
|
1443
|
+
Compaction summarizes the conversation arc but loses the durable facts. Threadnote's hook captures them
|
|
1444
|
+
first; the post-compaction turn recalls them and resumes without amnesia.
|
|
1445
|
+
</div>
|
|
1446
|
+
</div>
|
|
1447
|
+
|
|
1448
|
+
<div class="vignette reveal">
|
|
1449
|
+
<div class="v-say">Remember that this repo cuts release notes from CI via gh release create.</div>
|
|
1450
|
+
<pre class="v-call">remember_context({kind: "durable", project: "<repo>", topic: "release-process", text: "..."})</pre>
|
|
1451
|
+
<pre class="v-response">Stored: viking://user/you/memories/durable/projects/<repo>/release-process.md</pre>
|
|
1452
|
+
<div class="v-answer">
|
|
1453
|
+
Next time anyone asks where releases happen, the agent finds it in two seconds. No grepping the wiki.
|
|
1454
|
+
</div>
|
|
1455
|
+
</div>
|
|
1456
|
+
|
|
1457
|
+
<div class="vignette reveal">
|
|
1458
|
+
<div class="v-say">What did we conclude about the export-workflow timeout?</div>
|
|
1459
|
+
<pre class="v-call">recall_context({query: "export workflow timeout findings"})</pre>
|
|
1460
|
+
<pre class="v-response">→ viking://user/you/memories/durable/projects/<repo>/export-timeout.md (score 0.71)</pre>
|
|
1461
|
+
<div class="v-answer">
|
|
1462
|
+
Re-open the same investigation three weeks later; the durable memory points your agent at the right
|
|
1463
|
+
files and the resolution. The trail doesn't decay.
|
|
1464
|
+
</div>
|
|
1465
|
+
</div>
|
|
1466
|
+
</div>
|
|
1467
|
+
</div>
|
|
1468
|
+
</section>
|
|
1469
|
+
|
|
1412
1470
|
<!-- 13. CLOSE -->
|
|
1413
1471
|
<section id="close" class="slide">
|
|
1414
1472
|
<div class="slide-inner">
|
|
@@ -1538,6 +1596,27 @@ threadnote doctor --dry-run</code></pre>
|
|
|
1538
1596
|
}
|
|
1539
1597
|
});
|
|
1540
1598
|
})();
|
|
1599
|
+
|
|
1600
|
+
// Replace the hardcoded version pill with whatever npm currently
|
|
1601
|
+
// serves as latest. Fails silently and keeps the fallback text on any
|
|
1602
|
+
// network or registry error — the deck must render even offline.
|
|
1603
|
+
(async () => {
|
|
1604
|
+
const tag = document.getElementById('version-tag');
|
|
1605
|
+
if (!tag) return;
|
|
1606
|
+
try {
|
|
1607
|
+
const response = await fetch('https://registry.npmjs.org/threadnote/latest', {
|
|
1608
|
+
headers: {accept: 'application/json'},
|
|
1609
|
+
signal: AbortSignal.timeout(3000),
|
|
1610
|
+
});
|
|
1611
|
+
if (!response.ok) return;
|
|
1612
|
+
const data = await response.json();
|
|
1613
|
+
if (typeof data.version === 'string' && data.version.length > 0) {
|
|
1614
|
+
tag.textContent = 'v' + data.version;
|
|
1615
|
+
}
|
|
1616
|
+
} catch {
|
|
1617
|
+
// Keep the static fallback.
|
|
1618
|
+
}
|
|
1619
|
+
})();
|
|
1541
1620
|
</script>
|
|
1542
1621
|
</body>
|
|
1543
1622
|
</html>
|