Skip to content

Commit b1b72d1

Browse files
committed
Simplify note.py with Typer and stdin input
- Use Typer for CLI parsing - Content read from stdin - Required: --title, Optional: --slug, --tags - Always prints formatted note to stdout - --save flag writes to .knowledge/notes/<slug>.md - Inline script metadata for uv dependencies
1 parent 9d2b676 commit b1b72d1

6 files changed

Lines changed: 153 additions & 305 deletions

File tree

.knowledge/notes/auth-thoughts.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
title: "Auth Thoughts"
3+
slug: auth-thoughts
4+
date: 2026-03-27
5+
tags:
6+
- auth
7+
- oauth
8+
---
9+
10+
# Auth Thoughts
11+
12+
This is my note content about auth flow.

.opencode/bin/note

Lines changed: 0 additions & 158 deletions
This file was deleted.

.opencode/bin/note.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env python3
2+
# /// script
3+
# requires-python = ">=3.10"
4+
# dependencies = [
5+
# "typer", "pyyaml"
6+
# ]
7+
# ///
8+
9+
"""Create structured notes.
10+
11+
Usage:
12+
uv run note --title "My Note" [--slug my-note] [--tags "tag1,tag2"] < content.txt
13+
uv run note --title "My Note" --save < content.txt
14+
"""
15+
import sys
16+
from datetime import datetime
17+
from pathlib import Path
18+
19+
import typer
20+
21+
app = typer.Typer(help="Create structured notes")
22+
NOTES_DIR = Path(".knowledge/notes")
23+
24+
25+
def slugify(title: str) -> str:
26+
"""Convert title to URL-safe slug."""
27+
import re
28+
return re.sub(r"[^a-z0-9]+", "-", title.lower()).strip("-")
29+
30+
31+
def format_note(title: str, slug: str, tags: list[str], content: str) -> str:
32+
"""Format note with YAML frontmatter."""
33+
date = datetime.now().strftime("%Y-%m-%d")
34+
35+
lines = ["---"]
36+
lines.append(f'title: "{title}"')
37+
lines.append(f"slug: {slug}")
38+
lines.append(f"date: {date}")
39+
lines.append("tags:")
40+
for tag in tags:
41+
lines.append(f" - {tag}")
42+
lines.append("---")
43+
lines.append("")
44+
lines.append(f"# {title}")
45+
lines.append("")
46+
lines.append(content)
47+
48+
return "\n".join(lines)
49+
50+
51+
@app.command()
52+
def main(
53+
title: str = typer.Option(..., "--title", "-t", help="Note title"),
54+
slug: str | None = typer.Option(None, "--slug", "-s", help="URL slug (auto-generated from title if not provided)"),
55+
tags: str = typer.Option("", "--tags", help="Comma-separated tags"),
56+
save: bool = typer.Option(False, "--save", help="Save to file (prints to stdout regardless)"),
57+
):
58+
"""Create a structured note from stdin content."""
59+
# Read content from stdin
60+
content = sys.stdin.read().strip()
61+
62+
if not content:
63+
typer.echo("Error: No content provided via stdin", err=True)
64+
raise typer.Exit(1)
65+
66+
# Generate slug if not provided
67+
if not slug:
68+
slug = slugify(title)
69+
70+
# Parse tags
71+
tag_list = [t.strip() for t in tags.split(",") if t.strip()]
72+
73+
# Format the note
74+
formatted = format_note(title, slug, tag_list, content)
75+
76+
# Print to stdout
77+
print(formatted)
78+
79+
# Save if requested
80+
if save:
81+
NOTES_DIR.mkdir(parents=True, exist_ok=True)
82+
filepath = NOTES_DIR / f"{slug}.md"
83+
84+
if filepath.exists():
85+
typer.echo(f"\nError: File already exists: {filepath}", err=True)
86+
raise typer.Exit(1)
87+
88+
filepath.write_text(formatted)
89+
typer.echo(f"\n✓ Saved to: {filepath}")
90+
91+
92+
if __name__ == "__main__":
93+
app()

.opencode/commands/note.md

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,76 @@
11
# /note Command
22

3-
Create structured notes from raw thoughts.
3+
Create structured notes from content via stdin.
44

55
## Usage
66

77
```
8-
/note <your raw thoughts>
8+
/note --title "Title" [--tags "tag1,tag2"] [--save]
99
```
1010

1111
## How It Works
1212

13-
The model runs the `note` CLI tool:
13+
Model pipes content to `note.py` via stdin:
1414

15-
1. **Create**: `uv run note create --content "..."`
16-
2. **Review**: Model presents structured note
17-
3. **Iterate**: Re-run with modifications if needed
18-
4. **Save**: `uv run note save --content "..." --filename "name"`
15+
```bash
16+
echo "Note content..." | uv run note --title "Title" --tags "tag1"
17+
```
18+
19+
## CLI Options
1920

20-
## CLI Tool
21+
- `--title, -t` (required) - Note title
22+
- `--slug, -s` (optional) - URL slug (auto-generated from title)
23+
- `--tags` (optional) - Comma-separated tags
24+
- `--save` (flag) - Save to file (always prints to stdout)
2125

22-
**Location**: `.opencode/bin/note`
26+
## Example
2327

24-
**Commands**:
28+
```
29+
User: /note "Auth Design Thoughts"
2530
26-
```bash
27-
# Structure content into note
28-
uv run note create --content "Your thoughts..."
31+
Model: echo "I was thinking about auth flow. We need OAuth2..." | \
32+
uv run note --title "Auth Design Thoughts" --tags "auth,design"
2933
30-
# Save to file
31-
uv run note save --content "..." --filename "name"
34+
Output:
35+
---
36+
title: "Auth Design Thoughts"
37+
slug: auth-design-thoughts
38+
date: 2026-03-27
39+
tags:
40+
- auth
41+
- design
42+
---
3243
33-
# List existing notes
34-
uv run note list
44+
# Auth Design Thoughts
3545
36-
# Search notes
37-
uv run note search --query "auth"
38-
```
46+
I was thinking about auth flow. We need OAuth2...
3947
40-
## Example
48+
User: Save it
4149
50+
Model: [re-runs with --save flag]
4251
```
43-
User: /note "I was thinking about auth flow. We need OAuth2."
4452

45-
Model: uv run note create --content "I was thinking about auth flow..."
53+
## Output
4654

47-
Output:
48-
{
49-
"id": "2026-03-27-abc123",
50-
"title": "Auth Flow Thoughts",
51-
"created": "2026-03-27",
52-
"type": "note",
53-
"tags": ["auth"],
54-
"filename": "auth-flow-thoughts"
55-
}
55+
Always prints YAML frontmatter + Markdown to stdout:
5656

57-
Model: Here's your note with tags: auth. Save as "auth-flow-thoughts"?
57+
```yaml
58+
---
59+
title: "My Title"
60+
slug: my-title
61+
date: 2026-03-27
62+
tags:
63+
- tag1
64+
- tag2
65+
---
5866

59-
User: Yes
67+
# My Title
6068

61-
Model: uv run note save --content "..." --filename "auth-flow-thoughts"
69+
Content from stdin...
6270
```
6371

64-
Notes saved to: `.knowledge/notes/<filename>.md`
72+
With `--save`, also writes to: `.knowledge/notes/<slug>.md`
73+
74+
## Script Location
75+
76+
`.opencode/bin/note.py` (inline script with uv dependencies)

.python-version

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)