Skip to content

feat: sprout notes NIP-23 long-form CLI + relay a-tag deletion#719

Merged
tlongwell-block merged 1 commit into
mainfrom
notes-cli-combined
May 22, 2026
Merged

feat: sprout notes NIP-23 long-form CLI + relay a-tag deletion#719
tlongwell-block merged 1 commit into
mainfrom
notes-cli-combined

Conversation

@tlongwell-block
Copy link
Copy Markdown
Collaborator

What

The complete long-form notes feature in one change: the sprout notes CLI plus the relay-side NIP-09 a-tag deletion fix it depends on. Supersedes #718 (CLI) and #716 (relay).

CLI — sprout notes (kind:30023)

Editable team knowledge base. Write a skill once; reference the naddr from agent memory instead of re-deriving it.

verb behavior
set --name <slug> [--title][--summary][--tag t...][--clear-tags] --content - Idempotent upsert keyed by (kind:30023, me, d=slug). Read-before-write preserves published_at; carries title/summary/tags when omitted, ""/--clear-tags clears. --title required on first publish. Prints durable refs.
get (--naddr | --name <slug> [--author <ref>]) [--content-only] Exact by coordinate; cross-author #d lookup by name. >1 hit → candidates + non-zero exit.
ls [--author <ref>] [--tag t] [--limit N] Own by default; --author all; bounded (50/200).

Relay — NIP-09 a-tag deletion (#714)

handle_a_tag_deletion no-op'd for kind:30023. Adds soft_delete_by_coordinate and routes every NIP-33 kind through it, so a-tag deletion is authoritative for addressable events. Workflow branch unchanged.

notes rm

Intentionally not shipped in this PR. Its design (dual-tag emit) and the relay path it needs are both here, so it's a small follow-up — held for your sign-off on whether v1 wants delete.

Testing

Combined tree, full local suites: sprout-cli 98/98 · sprout-db 64/64 · sprout-relay 192/192 · clippy -D warnings clean · fmt clean. e2e (#[ignore], relay-gated): set-twice-preserves-published_at + a-tag-deletion round-trips. Live e2e + ACP-harness exercise in progress on a local relay — results to follow.

One DCO-signed commit (Tyler), co-authored Dawn / Max / Quinn.

Combines the long-form notes CLI with its relay-side companion so the full
feature lands as one reviewable change.

## CLI (`sprout notes`)
Editable team-knowledge notes on kind:30023 — write a skill once, reference
the naddr from agent memory instead of re-deriving it.
- `set --name <slug> [--title][--summary][--tag t...][--clear-tags] --content -`
  Idempotent upsert keyed by (kind:30023, me, d=slug). Read-before-write
  preserves `published_at`, carries title/summary/tags when omitted; `""` /
  `--clear-tags` clears. `--title` required on first publish. Prints durable
  refs (event id, naddr, coordinate, slug).
- `get (--naddr | --name <slug> [--author <ref>]) [--content-only]`
  Exact by coordinate; cross-author `#d` lookup by name. >1 hit → candidates
  + non-zero exit. Never guesses.
- `ls [--author <ref>] [--tag t] [--limit N]` — own by default; `--author all`
  across the team; bounded (default 50, cap 200).
- `rm --name <slug>` — NIP-09 deletion (kind:5) of your own note. Read-before-write
  gives a clean "nothing to delete" on a missing slug; the deletion carries an
  `a` tag *only* (no `e` tag), which is required for the relay's coordinate
  soft-delete path below to fire.

Standard NIP-23 tags only; global, no h-tag.

## Relay (NIP-09 a-tag deletion, #714)
`handle_a_tag_deletion` no-op'd for kind:30023 — a kind:5 targeting the
addressable coordinate was accepted but never soft-deleted the row. Adds
`soft_delete_by_coordinate` (sprout-db) and routes every NIP-33 kind through
it, so a-tag deletion is authoritative for 30023 and all addressable kinds.
The workflow branch keeps its bespoke handling.

## Tests
Pure carry-forward (`build_set_event`), tag parsing (`NoteSnapshot::from_event`),
and the deletion builder (`build_rm_event` — asserts a-tag-only, zero `e` tags)
are unit-tested. `e2e_long_form` gains set-twice-preserves-published_at and
a-tag-deletion round-trips. Verified live against a local relay: all ignored
e2e pass, and the full `set → get → ls → rm → get-404` lifecycle round-trips
via the `sprout notes` binary (and via an ACP agent driving it over shell).
TESTING.md gains a `notes` runbook section.

Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Max (sprout agent) <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Quinn (sprout agent) <96f056ad5f2305c8ddf637dc65d048aa4c12d7daeb8867690e34fca46b0ef64c@sprout-oss.stage.blox.sqprod.co>
@tlongwell-block tlongwell-block merged commit 504cfea into main May 22, 2026
15 checks passed
@tlongwell-block tlongwell-block deleted the notes-cli-combined branch May 22, 2026 02:30
wpfleger96 added a commit that referenced this pull request May 22, 2026
PR #719 (NIP-23 long-form notes) merged to main with pre-0.44 API
calls. Apply the same EventBuilder and Tag::parse migrations.

Also fix matching dms.rs breakage (same Tag::parse/EventBuilder::new
pattern) that blocked compilation, and replace the deprecated
Timestamp::as_u64() with as_secs() in notes.rs.
wpfleger96 added a commit that referenced this pull request May 22, 2026
PR #719 E2E test file and notes.rs test code still used deprecated
Timestamp::as_u64(), old Tag::parse(&[]) signature, 3-arg
EventBuilder::new(), and array-form custom_tag().
wpfleger96 added a commit that referenced this pull request May 22, 2026
PR #719 (NIP-23 long-form notes) merged to main with pre-0.44 API
calls. Apply the same EventBuilder and Tag::parse migrations.

Also fix matching dms.rs breakage (same Tag::parse/EventBuilder::new
pattern) that blocked compilation, and replace the deprecated
Timestamp::as_u64() with as_secs() in notes.rs.
wpfleger96 added a commit that referenced this pull request May 22, 2026
PR #719 E2E test file and notes.rs test code still used deprecated
Timestamp::as_u64(), old Tag::parse(&[]) signature, 3-arg
EventBuilder::new(), and array-form custom_tag().
wpfleger96 added a commit that referenced this pull request May 22, 2026
PR #719 (NIP-23 long-form notes) merged to main with pre-0.44 API
calls. Apply the same EventBuilder and Tag::parse migrations.

Also fix matching dms.rs breakage (same Tag::parse/EventBuilder::new
pattern) that blocked compilation, and replace the deprecated
Timestamp::as_u64() with as_secs() in notes.rs.
wpfleger96 added a commit that referenced this pull request May 22, 2026
PR #719 E2E test file and notes.rs test code still used deprecated
Timestamp::as_u64(), old Tag::parse(&[]) signature, 3-arg
EventBuilder::new(), and array-form custom_tag().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant