sticky-note-cli 2.5.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sticky Note Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,456 @@
1
+ <p align="center">
2
+ <!-- Replace with your own logo -->
3
+ <img src="docs/images/logo.png" alt="Sticky Note" width="600" />
4
+ </p>
5
+ <p align="center">
6
+ <strong>Human-to-human handoff for AI coding assistants.</strong><br/>
7
+ Git-backed shared memory that captures session threads and surfaces<br/>
8
+ teammate context — automatically, inside the tools you already use.
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/sticky-note"><img src="https://img.shields.io/npm/v/sticky-note.svg?style=flat-square&color=f59e0b" alt="npm version" /></a>
13
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="MIT License" /></a>
14
+ <a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D16-brightgreen.svg?style=flat-square" alt="Node.js >= 16" /></a>
15
+ <a href="#supported-tools"><img src="https://img.shields.io/badge/works%20with-Claude%20%C2%B7%20Copilot%20%C2%B7%20Codex-8b5cf6?style=flat-square" alt="Works with Claude, Copilot, Codex" /></a>
16
+ </p>
17
+
18
+ <br/>
19
+
20
+ <p align="center">
21
+ <img src="https://raw.githubusercontent.com/BandaruDheeraj/sticky-note/main/docs/images/architecture.svg" alt="Architecture diagram" width="800" />
22
+ </p>
23
+
24
+ <br/>
25
+
26
+ > [!NOTE]
27
+ > **Sticky Note is evolving.** Features, APIs, and file formats may change as we learn what works best for teams.
28
+
29
+ ---
30
+
31
+ ## The Problem
32
+
33
+ Every developer using AI coding assistants starts every session from zero.
34
+ The handoff between teammates happens in Slack and stand-ups — everywhere
35
+ except inside the AI tool where the work actually happened.
36
+
37
+ ## The Solution
38
+
39
+ Sticky Note captures what happened in each AI session (files touched, status,
40
+ narrative, failed approaches) and surfaces it to teammates automatically on
41
+ their next session start — ranked by relevance. No dashboards. No extra tools.
42
+ Just shared files in your repo.
43
+
44
+ ---
45
+
46
+ ## What's New in V2.5
47
+
48
+ - **Smart injection (two-tier)**: Stuck threads injected eagerly at session start; all other threads injected lazily when you first touch a file they authored — via built-in git blame attribution
49
+ - **Thread resume (local)**: `npx sticky-note resume-thread --query "auth fix" --user alice` — natural language thread discovery with text similarity + file attribution ranking
50
+ - **Built-in attribution engine**: `npx sticky-note get-line-attribution --file src/auth.ts` — maps file lines to commit SHAs via git blame, resolves to threads with line ranges. No external dependencies.
51
+ - **Git Notes storage**: Session attribution stored in `refs/notes/sticky-note` — survives rebase/amend
52
+ - **Three-tier SHA resolution**: Git Notes → Audit JSONL → File+date heuristic — attribution never breaks
53
+ - **PreToolUse hook**: New hook fires before each tool call for lazy injection with line-range detail
54
+ - **Thread schema additions**: `contributors[]`, `resumed_by`, `resumed_at`, `resume_history[]` — multi-contributor threads with full resume chain
55
+
56
+ ### What's New in V2
57
+
58
+ - **Per-user audit & presence**: Audit logs and presence in per-user files under `audit/` and `presence/` — committed and shared with the team
59
+ - **Relevance scoring**: Context injected based on file overlap, branch match, and recency
60
+ - **Richer threads**: Narrative summaries, failed approaches, work type, activities
61
+ - **Tombstone expiry**: Old threads are automatically cleaned up via `gc`
62
+ - **Presence tracking**: See who's currently active with `npx sticky-note who`
63
+ - **Codex support**: Wrapper script for post-session capture
64
+ - **Separate config**: Team settings in `sticky-note-config.json`
65
+
66
+ ---
67
+
68
+ ## Quick Start
69
+
70
+ ### 1. Install
71
+
72
+ ```bash
73
+ npx sticky-note init
74
+ ```
75
+
76
+ This runs an interactive setup that:
77
+ - [OK] Checks for git and Node.js 16+
78
+ - 📋 Asks for team config (MCP servers, conventions, stale days)
79
+ - 📁 Creates all hook scripts and config files
80
+
81
+ ### 2. Commit
82
+
83
+ ```bash
84
+ git add .claude .github .sticky-note .gitignore .gitattributes CLAUDE.md
85
+ git commit -m "feat: add sticky-note hooks"
86
+ ```
87
+
88
+ ### 3. Push & Pull
89
+
90
+ ```bash
91
+ git push # Share with team
92
+ git pull # Teammates — no additional setup needed
93
+ ```
94
+
95
+ ### 4. Work
96
+
97
+ Open Claude Code or Copilot CLI and start working. Sticky Note runs
98
+ in the background via hooks — capturing threads and surfacing context.
99
+
100
+ **First thing to try** — ask your AI agent:
101
+
102
+ > "Show me the active sticky note threads"
103
+
104
+ ---
105
+
106
+ ## How Context Gets Injected
107
+
108
+ Sticky Note injects context through **four mechanisms**: two that run
109
+ automatically via hooks, one triggered manually via the CLI, and one
110
+ that's always available as a static file.
111
+
112
+ ### 1. Static Instruction Files (always available)
113
+
114
+ `npx sticky-note init` deploys AI instruction files that teach each tool
115
+ how to interact with Sticky Note:
116
+
117
+ | File | Consumed by | Installed to |
118
+ |------|-------------|--------------|
119
+ | `CLAUDE.md` | Claude Code | repo root |
120
+ | `copilot-instructions.md` | Copilot CLI | `.github/` |
121
+
122
+ These files contain thread field references, status icons, resume
123
+ instructions, display formats, and query examples. They're wrapped in
124
+ `<!-- sticky-note:start/end -->` markers so `npx sticky-note update` can
125
+ refresh them without overwriting your own content.
126
+
127
+ ### 2. Session Start Hook (`session-start.js`)
128
+
129
+ Runs once when a session begins. V2.5 uses **eager injection** for stuck
130
+ threads only — non-stuck threads are held for lazy injection.
131
+
132
+ - **Resumed thread** — If a `.sticky-resume` signal file exists, the full
133
+ thread payload is injected: narrative, files touched, failed approaches,
134
+ conversation prompts, and the complete resume chain history.
135
+ - **Stuck threads** — All stuck threads are injected eagerly (V2.5).
136
+ - **Team config** — Conventions, MCP servers, and skills from
137
+ `sticky-note-config.json`.
138
+ - **Active presence** — Developers seen in the last 15 minutes and the
139
+ files they're working on.
140
+
141
+ The hook also clears the injected-this-session tracking set, snapshots
142
+ `HEAD`, generates a session ID, and ages stale threads.
143
+
144
+ ### 3. Per-Prompt Injection (`inject-context.js`)
145
+
146
+ Runs on **every user prompt**. Scores all live threads by relevance and
147
+ injects the top 3–5 (under token budget) as additional context.
148
+ **V2.5:** Skips threads already injected by session-start or PreToolUse.
149
+
150
+ | Signal | Weight | Description |
151
+ |--------|--------|-------------|
152
+ | File overlap | 3 | Thread files match your recent git changes |
153
+ | Branch match | 2 | Thread is on your current branch |
154
+ | Recency | 2 | Decays 0.2 per day from last activity |
155
+ | Stuck status | +2 | Boost for threads marked stuck |
156
+ | Prompt keywords | 1 | File names mentioned in your prompt |
157
+ | Same developer | 1 | Your own previous threads |
158
+ | Resume signal | +10 | Thread targeted by `.sticky-resume` |
159
+
160
+ ### 3b. PreToolUse Hook (`pre-tool-use.js`) — V2.5
161
+
162
+ Runs **before each tool call**. Lazy injection tier:
163
+
164
+ 1. Extracts target file from tool input
165
+ 2. Runs `git blame --line-porcelain <file>` → commit SHAs per line
166
+ 3. Three-tier SHA resolution: Git Notes → Audit JSONL → File+date heuristic
167
+ 4. Resolves session IDs → loads threads with line ranges
168
+ 5. Injects matching threads (if not already injected this session)
169
+
170
+ No external dependencies — uses built-in git blame.
171
+
172
+ ### 4. Resume Flow (`npx sticky-note resume <id>`)
173
+
174
+ A manual trigger that enables **cross-tool handoff** (e.g., Claude Code →
175
+ Copilot CLI):
176
+
177
+ ```
178
+ npx sticky-note resume <thread-id>
179
+ ```
180
+
181
+ 1. Writes the thread UUID to a `.sticky-resume` signal file.
182
+ 2. Outputs the thread's full context to the terminal (narrative, files,
183
+ failed approaches, conversation prompts).
184
+ 3. On the next session start, `session-start.js` detects the signal,
185
+ reopens the thread as `open`, and injects the complete payload.
186
+ 4. `inject-context.js` gives the resumed thread a +10 score boost on
187
+ every prompt for the duration of the session.
188
+ 5. `session-end.js` clears the signal file and updates the thread's
189
+ `resume_chain` with the new session.
190
+
191
+ This means a thread started in Claude Code can be resumed in Copilot CLI
192
+ (or vice versa) with full context preserved — including the original
193
+ conversation prompts.
194
+
195
+ ---
196
+
197
+ ## How Context Gets Collected
198
+
199
+ The injection hooks above are fed by four **collection hooks** that run
200
+ silently in the background:
201
+
202
+ ### Tool Tracking (`track-work.js`)
203
+
204
+ Runs after every tool use. Appends a JSONL audit entry with the tool
205
+ name, file path, and session ID. Also updates the user's presence file
206
+ (`presence/<username>.json`) so `session-start.js` can show who's active.
207
+
208
+ ### Session End (`session-end.js`)
209
+
210
+ Runs when a session ends. Captures the full thread record:
211
+
212
+ - **Files touched** — from audit trail, transcript parsing, and git diff
213
+ against the HEAD snapshot from session start.
214
+ - **Narrative** — last assistant message (300 char max).
215
+ - **Work type** — inferred from activity patterns (bug-fix, feature,
216
+ debugging, testing, documentation, etc.).
217
+ - **Failed approaches** — extracted where error + retry patterns both match.
218
+ - **Prompts** — stored for cross-tool resume (up to 20, 300 chars each).
219
+ - **Tool calls** — counts per tool (Edit, Read, Write, etc.).
220
+
221
+ Also runs a lazy tombstone sweep: closed threads older than `stale_days`
222
+ are expired to minimal footprint.
223
+
224
+ ### Error Capture (`on-error.js`)
225
+
226
+ Runs when a tool execution fails. Creates or updates the session thread
227
+ with status `stuck` and appends the error to `failed_approaches`. Next
228
+ session's `inject-context.js` ranks stuck threads higher so teammates
229
+ see them.
230
+
231
+ ### Stop Handler (`on-stop.js`, Claude Code only)
232
+
233
+ Runs when the user stops a session. Builds a structured handoff summary
234
+ (what was done, what failed, current status, next steps) and saves it to
235
+ the thread's `handoff_summary` field.
236
+
237
+ ---
238
+
239
+ ## What Gets Captured
240
+
241
+ | Data | Captured | Example |
242
+ |-------------------|----------|--------------------------------------|
243
+ | Files touched | [OK] | `src/auth.ts`, `lib/db.py` |
244
+ | Thread status | [OK] | open, stuck, stale, closed, expired |
245
+ | Author | [OK] | OS username |
246
+ | Timestamp | [OK] | ISO 8601 |
247
+ | Narrative | [OK] | "Fixed auth token refresh flow" |
248
+ | Failed approaches | [OK] | What was tried, errors, files |
249
+ | Work type | [OK] | bug-fix, feature, debugging, etc. |
250
+ | Code content | [ERR] | Never captured |
251
+ | Conversation | [ERR] | Never captured |
252
+ | Credentials | [ERR] | Never captured |
253
+
254
+ ---
255
+
256
+ ## Thread Lifecycle
257
+
258
+ ```
259
+ open → stale (auto, after stale_days with no activity)
260
+ open → closed (on session end)
261
+ stuck → closed (on session end or manual)
262
+ closed → open (via `npx sticky-note resume <id>`)
263
+ closed → expired (auto, tombstoned by gc after stale_days)
264
+ ```
265
+
266
+ Expired threads keep only their ID, status, user, and closed timestamp.
267
+
268
+ ---
269
+
270
+ ## File Structure
271
+
272
+ ```
273
+ CLAUDE.md # AI instructions for Claude Code
274
+
275
+ .claude/
276
+ ├── settings.json # Claude Code hook config
277
+ └── hooks/
278
+ ├── sticky-utils.js # Shared utilities
279
+ ├── session-start.js # Load & inject teammate context
280
+ ├── session-end.js # Capture session thread
281
+ ├── inject-context.js # Per-prompt relevance scoring
282
+ ├── pre-tool-use.js # Lazy injection via git blame attribution (V2.5)
283
+ ├── sticky-attribution.js # Built-in attribution engine (V2.5)
284
+ ├── sticky-git-notes.js # Git Notes utilities (V2.5)
285
+ ├── track-work.js # JSONL audit + presence + line tracking (V2.5)
286
+ ├── parse-transcript.js # Narrative + failed approach extraction
287
+ ├── on-stop.js # Handoff summary on stop
288
+ ├── on-error.js # Stuck thread on error
289
+ ├── post-rewrite.js # Git Notes rewrite survival (V2.5)
290
+ └── sticky-codex.sh # Optional Codex wrapper
291
+
292
+ .github/
293
+ ├── copilot-instructions.md # AI instructions for Copilot CLI
294
+ └── hooks/
295
+ └── hooks.json # Copilot CLI hook config
296
+
297
+ .sticky-note/
298
+ ├── sticky-note.json # Shared threads (git-tracked)
299
+ ├── sticky-note-config.json # Team config (git-tracked)
300
+ ├── audit/ # Per-user audit logs (git-tracked)
301
+ │ └── <username>.jsonl # One file per team member
302
+ ├── presence/ # Per-user presence (git-tracked)
303
+ │ └── <username>.json # One file per team member
304
+ ├── .sticky-resume # Resume signal (local only)
305
+ ├── .sticky-injected # Injection tracking (local only, V2.5)
306
+ └── .sticky-active-resume # Active resume marker (local only, V2.5)
307
+ ```
308
+
309
+ ---
310
+
311
+ ## CLI Commands
312
+
313
+ ```bash
314
+ npx sticky-note init # Interactive setup
315
+ npx sticky-note init --codex # Setup with Codex wrapper
316
+ npx sticky-note update # Update hook scripts (preserves data)
317
+ npx sticky-note status # Diagnostic report (includes attribution health)
318
+ npx sticky-note threads # List threads with status icons
319
+ npx sticky-note resume # List resumable threads
320
+ npx sticky-note resume <id> # Resume a previous thread
321
+ npx sticky-note resume --clear # Cancel active resume
322
+ npx sticky-note resume-thread # Smart resume: --query, --user, --file (V2.5)
323
+ npx sticky-note audit # Query merged audit trail (all users)
324
+ npx sticky-note who # Show active and recent team members
325
+ npx sticky-note switch <branch> # Safe branch switch (auto-stashes data)
326
+ npx sticky-note gc # Tombstone expired threads
327
+ npx sticky-note reset # Wipe all threads (--force, --keep-audit)
328
+ npx sticky-note get-line-attribution # File→thread attribution with line ranges (V2.5)
329
+ npx sticky-note checkpoint # Set work-topic checkpoint for attribution (V2.5)
330
+ npx sticky-note --version # Show version
331
+ npx sticky-note --help # Show help
332
+ ```
333
+
334
+ ### Audit Filters
335
+
336
+ ```bash
337
+ npx sticky-note audit --user alice
338
+ npx sticky-note audit --file src/auth.ts
339
+ npx sticky-note audit --since 2025-01-01
340
+ npx sticky-note audit --session abc-123
341
+ npx sticky-note audit --limit 100
342
+ ```
343
+
344
+ ---
345
+
346
+ ## Configuration
347
+
348
+ Edit `.sticky-note/sticky-note-config.json`:
349
+
350
+ ```json
351
+ {
352
+ "stale_days": 14,
353
+ "mcp_servers": [],
354
+ "skills": [],
355
+ "conventions": ["Use TypeScript strict mode", "Test before commit"],
356
+ "hook_version": "2.5.0"
357
+ }
358
+ ```
359
+
360
+ | Key | Description | Default |
361
+ |----------------|------------------------------------------|---------|
362
+ | `stale_days` | Days before threads expire + gc cleanup | `14` |
363
+ | `mcp_servers` | Shared MCP server references | `[]` |
364
+ | `skills` | Team skill definitions | `[]` |
365
+ | `conventions` | Team coding conventions (injected) | `[]` |
366
+
367
+ ---
368
+
369
+ ## Requirements
370
+
371
+ - **Git** repository (any host)
372
+ - **Node.js 16+** (for hook scripts and `npx` CLI)
373
+ - **Claude Code**, **Copilot CLI**, and/or **Codex**
374
+
375
+ ---
376
+
377
+ ## Supported Tools
378
+
379
+ | Tool | Hook Config | Integration |
380
+ |-------------|-----------------------------|---------------------------------|
381
+ | Claude Code | `.claude/settings.json` | Full — all 6 hooks + transcript |
382
+ | Copilot CLI | `.github/hooks/hooks.json` | Full — all hooks |
383
+ | Codex | `sticky-codex.sh` wrapper | Post-session capture |
384
+
385
+ All tools call the same JavaScript hooks and share the same data files.
386
+
387
+ ---
388
+
389
+ ## Concurrent Usage & Merge Strategy
390
+
391
+ `npx sticky-note init` adds a `.gitattributes` rule:
392
+
393
+ ```
394
+ .sticky-note/sticky-note.json merge=union
395
+ ```
396
+
397
+ This tells git to **keep lines from both sides** instead of conflicting.
398
+ Threads have unique UUIDs, so concurrent pushes merge cleanly.
399
+
400
+ Per-user audit logs (`audit/<username>.jsonl`) and presence files
401
+ (`presence/<username>.json`) are written by one user at a time, so they
402
+ never conflict.
403
+
404
+ ### Branch Switching
405
+
406
+ Sticky-note data (audit logs, presence, thread state) is **branch-independent** —
407
+ it's metadata about the repo, not part of the source code. However, because
408
+ these files are git-tracked and updated on every tool call, a raw
409
+ `git checkout` or `git switch` will fail if there are uncommitted changes.
410
+
411
+ Use one of these approaches:
412
+
413
+ ```bash
414
+ # Recommended: sticky-note CLI wrapper
415
+ npx sticky-note switch <branch>
416
+
417
+ # Or: git alias (set up by npx sticky-note init)
418
+ git sw <branch>
419
+ ```
420
+
421
+ Both auto-stash `.sticky-note/` before switching and restore it after.
422
+ See [docs/branch-switching.md](docs/branch-switching.md) for the full
423
+ design discussion.
424
+
425
+ ---
426
+
427
+ ## FAQ
428
+
429
+ **Q: Does this capture my code or conversations?**
430
+ A: No. Only file paths, timestamps, usernames, and status metadata.
431
+
432
+ **Q: What happens with merge conflicts in sticky-note.json?**
433
+ A: `merge=union` in `.gitattributes` handles most cases automatically.
434
+
435
+ **Q: Can I close a thread manually?**
436
+ A: Edit `sticky-note.json` and change the thread's `status` to `"closed"`,
437
+ or run `npx sticky-note gc` to tombstone expired threads.
438
+
439
+ **Q: Does this work offline?**
440
+ A: Yes. Everything is local until you `git push`.
441
+
442
+ **Q: How do I set up Codex?**
443
+ A: Run `npx sticky-note init --codex`, then alias the wrapper:
444
+ `alias sticky-codex=".claude/hooks/sticky-codex.sh"`
445
+
446
+ ---
447
+
448
+ ## License
449
+
450
+ [MIT](LICENSE) — fully open source, no restrictions.
451
+
452
+ ---
453
+
454
+ ## Contributing
455
+
456
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.