threadnote 0.3.8 → 0.4.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/README.md +4 -1
- package/dist/mcp_server.cjs +4082 -999
- package/dist/threadnote.cjs +931 -70
- package/docs/agent-instructions.md +34 -3
- package/docs/share.md +151 -0
- package/package.json +1 -1
|
@@ -8,9 +8,9 @@ Use OpenViking through Threadnote as a shared local context and memory layer. Re
|
|
|
8
8
|
follow the nearest `AGENTS.md`, `CLAUDE.md`, or other checked-in instruction file first.
|
|
9
9
|
|
|
10
10
|
When OpenViking MCP tools are available, use them directly. Prefer Threadnote-named MCP tools when present:
|
|
11
|
-
`recall_context`, `read_context`, `list_context`, and `
|
|
12
|
-
example `recall_context({"query":"current repo latest handoff"})`. Older Threadnote MCP adapters may
|
|
13
|
-
`search`, `read`, `list`, and `store` instead.
|
|
11
|
+
`recall_context`, `read_context`, `list_context`, `remember_context`, and `share_publish`. Always pass JSON arguments to
|
|
12
|
+
MCP tools, for example `recall_context({"query":"current repo latest handoff"})`. Older Threadnote MCP adapters may
|
|
13
|
+
expose `search`, `read`, `list`, and `store` instead.
|
|
14
14
|
|
|
15
15
|
If MCP is unavailable, use the `threadnote` CLI fallback.
|
|
16
16
|
|
|
@@ -93,6 +93,34 @@ them when it is safe:
|
|
|
93
93
|
|
|
94
94
|
Never compact secrets, credentials, customer data, raw production logs, or checked-in canonical docs into memory.
|
|
95
95
|
|
|
96
|
+
## Sharing memories with teammates
|
|
97
|
+
|
|
98
|
+
Threadnote can publish a curated subset of durable memories into a team git repo so other engineers' agents can pull them.
|
|
99
|
+
The mechanism lives under the `viking://user/<you>/memories/shared/<team>/...` subtree; only memories that are explicitly
|
|
100
|
+
published leave the machine. Personal handoffs, preferences, and unpublished durable notes always stay local.
|
|
101
|
+
|
|
102
|
+
Publish a durable memory when its content is useful to other engineers working on the same project (intended behavior,
|
|
103
|
+
design decisions, API contracts, gotchas) and is safe to share. Do NOT publish:
|
|
104
|
+
|
|
105
|
+
- handoffs or anything carrying machine-local paths, branch state, or in-flight task context;
|
|
106
|
+
- memories under `memories/preferences/`;
|
|
107
|
+
- anything mentioning secrets, customer data, raw logs, or material a teammate's git history shouldn't carry.
|
|
108
|
+
|
|
109
|
+
The MCP tool `share_publish` runs the same scrubber as the CLI and refuses to publish memories containing common secret
|
|
110
|
+
patterns (PEM private keys, `sk-...`, `gh[pousr]_...`, `Bearer ...`, `AKIA...`, `xox[abprs]-...`). It is a destructive
|
|
111
|
+
operation: it removes the personal copy after the shared copy is committed.
|
|
112
|
+
|
|
113
|
+
When a teammate's memory needs to come into your own working set, run `threadnote share sync` (no MCP equivalent yet) to
|
|
114
|
+
pull and reindex.
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
# MCP call shape
|
|
118
|
+
share_publish({"uri":"viking://user/you/memories/durable/projects/foo/bar.md"})
|
|
119
|
+
share_publish({"uri":"viking://user/you/memories/durable/projects/foo/bar.md","team":"friends","push":false})
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Before publishing, confirm with the user unless they have already instructed you to share durable memories autonomously.
|
|
123
|
+
|
|
96
124
|
## Handoff
|
|
97
125
|
|
|
98
126
|
Before pausing, switching agents, or ending meaningful work with local changes, store a concise handoff. Include:
|
|
@@ -123,4 +151,7 @@ threadnote remember --replace viking://user/example/memories/durable/projects/ex
|
|
|
123
151
|
threadnote archive viking://user/example/memories/handoffs/active/example/old-issue.md
|
|
124
152
|
threadnote forget viking://user/example/memories/events/duplicate.md
|
|
125
153
|
threadnote handoff --project example --topic active-issue --task "short task summary" --tests "checks run" --next-step "what to do next"
|
|
154
|
+
threadnote share init git@github.com:org/team-memories.git
|
|
155
|
+
threadnote share publish viking://user/example/memories/durable/projects/foo/bar.md
|
|
156
|
+
threadnote share sync
|
|
126
157
|
```
|
package/docs/share.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Sharing memories with teammates
|
|
2
|
+
|
|
3
|
+
`threadnote share` lets a small team keep a curated set of durable memories in a
|
|
4
|
+
git repository so every member's local agent can recall them. Personal handoffs,
|
|
5
|
+
preferences, and unpublished durable notes stay local; only memories you
|
|
6
|
+
explicitly publish leave your machine.
|
|
7
|
+
|
|
8
|
+
## Model in one screen
|
|
9
|
+
|
|
10
|
+
- A **team** is a configured shared repo. Each team has a name (default:
|
|
11
|
+
`default`), a git remote, a local working tree, and a separate gitdir.
|
|
12
|
+
- The working tree lives inside the OpenViking data tree at
|
|
13
|
+
`~/.openviking/data/viking/<account>/user/<you>/memories/shared/<team>/`. That
|
|
14
|
+
means files appearing in the worktree are also addressable as
|
|
15
|
+
`viking://user/<you>/memories/shared/<team>/...` and show up in normal
|
|
16
|
+
`recall`.
|
|
17
|
+
- The gitdir lives outside the OV data tree at
|
|
18
|
+
`~/.openviking/share/teams/<team>.gitdir/` so OpenViking never sees git
|
|
19
|
+
internals.
|
|
20
|
+
- Team configuration is recorded in `~/.openviking/share/teams.json` (mode
|
|
21
|
+
`0600`).
|
|
22
|
+
|
|
23
|
+
## Workflow
|
|
24
|
+
|
|
25
|
+
### One-time setup
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Create the repo first on GitHub/GitLab/etc. and copy its SSH URL.
|
|
29
|
+
threadnote share init git@github.com:org/team-memories.git
|
|
30
|
+
# Optional: add a second team
|
|
31
|
+
threadnote share init --team friends git@github.com:you/friends-memories.git
|
|
32
|
+
# Switch the default with init --set-default <name> or by running publish/sync
|
|
33
|
+
# with an explicit --team.
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`share init` clones the remote into your local memory tree and ingests any
|
|
37
|
+
existing markdown memories into OpenViking.
|
|
38
|
+
|
|
39
|
+
### See what's configured
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
threadnote share list
|
|
43
|
+
threadnote share status # default team
|
|
44
|
+
threadnote share status --team friends
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Share a memory
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# 1. Identify the personal URI you want to publish (use recall/list as usual).
|
|
51
|
+
# 2. Publish:
|
|
52
|
+
threadnote share publish viking://user/you/memories/durable/projects/foo/bar.md
|
|
53
|
+
# Optional flags: --team <name>, --message "...", --no-push, --dry-run.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`share publish` moves the memory from your personal namespace into the team's
|
|
57
|
+
shared subtree, commits with the message
|
|
58
|
+
`share: publish <relative-path>`, and pushes. The memory's recall path becomes
|
|
59
|
+
`viking://user/you/memories/shared/<team>/durable/projects/foo/bar.md`.
|
|
60
|
+
|
|
61
|
+
### Pull teammates' updates
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
threadnote share sync # default team
|
|
65
|
+
threadnote share sync --team friends # other team
|
|
66
|
+
threadnote share sync --no-push # pull only
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`share sync` will auto-commit any uncommitted edits in the worktree, fetch and
|
|
70
|
+
rebase from the remote, reindex pulled markdown files into OpenViking (so
|
|
71
|
+
`recall` finds them immediately), and push. Pass `--no-auto-commit` to refuse
|
|
72
|
+
syncing when the worktree is dirty.
|
|
73
|
+
|
|
74
|
+
### Take a memory back
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
threadnote share unpublish viking://user/you/memories/shared/default/durable/projects/foo/bar.md
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The memory is rewritten back into your personal namespace and removed from the
|
|
81
|
+
shared repo.
|
|
82
|
+
|
|
83
|
+
### Stop sharing for a team
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
threadnote share remove --team friends # deletes worktree + gitdir
|
|
87
|
+
threadnote share remove --team friends --keep-files
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`share remove` without `--keep-files` deletes the local checkout. Push any
|
|
91
|
+
unpushed commits first (`threadnote share sync` or `git -C <worktree> push`),
|
|
92
|
+
otherwise unpublished work is lost.
|
|
93
|
+
|
|
94
|
+
## Privacy & safety rules
|
|
95
|
+
|
|
96
|
+
- Only memories you actively publish leave your machine. `share init` will
|
|
97
|
+
refuse to clone over a non-empty worktree.
|
|
98
|
+
- `share publish` runs a best-effort scrubber over the memory text. It refuses
|
|
99
|
+
to publish if it matches any of:
|
|
100
|
+
- PEM private key headers (`-----BEGIN ... PRIVATE KEY-----`)
|
|
101
|
+
- OpenAI / Anthropic-style `sk-...` keys (16+ chars). Note: this also matches
|
|
102
|
+
any URL slug or random string starting with `sk-`; if you hit a false
|
|
103
|
+
positive on legitimate content, edit the memory to break the pattern.
|
|
104
|
+
- GitHub classic tokens (`gh[pousr]_...`)
|
|
105
|
+
- GitHub fine-grained PATs (`github_pat_...`)
|
|
106
|
+
- GitLab PATs (`glpat-...`)
|
|
107
|
+
- HTTP `Bearer ...` tokens (20+ chars)
|
|
108
|
+
- Bare JWTs (three base64url segments starting `eyJ...`) — catches a leaked
|
|
109
|
+
token even when the surrounding `Authorization: Bearer ` prefix has been
|
|
110
|
+
stripped. JWE tokens in legitimate documentation can collide; edit the
|
|
111
|
+
memory if the false positive is unavoidable.
|
|
112
|
+
- AWS access keys (`AKIA...`)
|
|
113
|
+
- Slack tokens (`xoxa`, `xoxb`, `xoxc`, `xoxd`, `xoxe`, `xoxp`, `xoxr`,
|
|
114
|
+
`xoxs`, with optional `-N-` segment markers — covers bot, user,
|
|
115
|
+
configuration, legacy cookie, refresh, app, and similar shapes)
|
|
116
|
+
- The scrubber complements but does not replace human review. Strip the value,
|
|
117
|
+
then retry.
|
|
118
|
+
- Only the `durable/` kind is shareable. `handoffs/`, `preferences/`,
|
|
119
|
+
`incidents/`, and other lifecycle kinds stay local by construction — both
|
|
120
|
+
the initial ingest (`share init`) and the sync-pull reindex (`share sync`)
|
|
121
|
+
skip any file outside `durable/`.
|
|
122
|
+
- `share publish` deletes the personal copy after publishing. If you want to
|
|
123
|
+
keep both, copy the memory to a new URI first (`ov read` then
|
|
124
|
+
`threadnote remember`).
|
|
125
|
+
- `share publish` refuses to overwrite an existing shared memory at the same
|
|
126
|
+
URI; forget the existing shared copy first or pick a different topic name.
|
|
127
|
+
|
|
128
|
+
## Conflict resolution
|
|
129
|
+
|
|
130
|
+
`share sync` uses `git pull --rebase` against the remote. When git can't merge
|
|
131
|
+
cleanly:
|
|
132
|
+
|
|
133
|
+
1. The pull command reports the conflict and leaves the worktree in a
|
|
134
|
+
rebase-in-progress state.
|
|
135
|
+
2. Resolve the conflicts manually in the worktree (it's a normal git checkout).
|
|
136
|
+
3. Run `git rebase --continue` (or `--abort`) yourself.
|
|
137
|
+
4. Re-run `threadnote share sync` to finish the reindex and push.
|
|
138
|
+
|
|
139
|
+
Two publishes touching the same `<topic>.md` from different machines will
|
|
140
|
+
collide; coordinate ownership per-topic, or use distinct topics.
|
|
141
|
+
|
|
142
|
+
## Cross-machine identity notes
|
|
143
|
+
|
|
144
|
+
Each user clones into their own user-namespaced path. A memory authored on
|
|
145
|
+
machine A as `viking://user/alice/memories/shared/team/durable/projects/foo/bar.md`
|
|
146
|
+
shows up on machine B as
|
|
147
|
+
`viking://user/bob/memories/shared/team/durable/projects/foo/bar.md`. The file
|
|
148
|
+
content (including any `supersedes:` URIs that reference the original author) is
|
|
149
|
+
identical, but explicit URI cross-references will point at the author's
|
|
150
|
+
namespace. For now, prefer narrative references ("see the foo memory under
|
|
151
|
+
shared/team") over URI links in shared content.
|