ZettelCLI is a desktop Command Line Interface (CLI) application used for managing a personal Zettelkasten note system. It is optimized for users who prefer keyboard commands over Graphical User Interfaces (GUI). Through just a keyboard, users can build their own repository of notes or quickly navigate through their knowledge base with ease.
- Ensure that you have Java 17 or above installed.
- Download the latest version of
ZettelCLIfrom the releases page, on the right side of the home page. (https://github.com/AY2526S1-CS2113-W13-1/tp) - Run the application:
java -jar zettel.jar| Command | Format | Description |
|---|---|---|
| Initialize Repository | init <repository-name> |
Create a new Zettelkasten repository |
| Change Repository | change-repo <repository-name> |
Switch to another existing repository |
| Current Repository | current-repo |
Display the name of the current repository |
| Add Note | new -t <TITLE> [-b <BODY>] |
Create a new note with optional body |
| Edit Note | edit <note-id> |
Edit an existing note |
| List Notes | list [-p] [-a] |
List notes (with optional filters) |
| Delete Note | delete [-f] <note-id> |
Delete a note by ID |
| Pin Note | pin <note-id> |
Pin a note to keep it at the top |
| Unpin Note | unpin <note-id> |
Unpin a previously pinned note |
| Archive Note | archive <note-id> |
Move note to archive folder |
| Unarchive Note | unarchive <note-id> |
Move note out of archive folder |
| Print Note Body | print-body <note-id> |
Display the full body of a note |
| Find Notes | find <text> |
Search for notes by text |
| Create Tag | new-tag <tag-name> |
Create a new global tag |
| Add Tag to Note | add-tag <note-id> <tag-name> |
Tag a note with an existing or new tag |
| List All Tags | list-tags-all |
List all global tags |
| List Note Tags | list-tags <note-id> |
List all tags on a specific note |
| Delete Tag from Note | delete-tag [-f] <note-id> <tag> |
Remove a tag from a specific note |
| Delete Tag Globally | delete-tag-globally [-f] <tag> |
Delete a tag from all notes globally |
| Rename Tag | rename-tag <old-tag> <new-tag> |
Rename a tag across all notes |
| Link Notes | link <source-id> <target-id> |
Create a one-way link from source to target |
| Unlink Notes | unlink <source-id> <target-id> |
Remove a one-way link from source to target |
| Link Both Directions | link-both <id1> <id2> |
Create links in both directions |
| Unlink Both Directions | unlink-both <id1> <id2> |
Remove all links between two notes |
| List Incoming Links | list-incoming-links <note-id> |
Show notes that link to this note |
| List Outgoing Links | list-outgoing-links <note-id> |
Show notes this note links to |
| Help | help |
Display all available commands |
| Exit | bye |
Exit the application |
Initializes a new Zettelkasten repository. This does not change the current repository, only creates a new one. User will have to use change-repo to change repository (See: Changing Repository)
Format:
init <repository-name>
Example:
init My_New_Repo
Expected Output:
Repository /My_New_Repo has been created.
Switches to another existing repository. The repository must have been previously created using the init command.
Format:
change-repo <repository-name>
or
change-repository <repository-name>
Example:
change-repo My_New_Repo
Expected Output:
Successfully changed to repository: /My_New_Repo
Displays the name of the currently active repository.
Format:
current-repo
or
current-repository
Expected Output:
Current repository: /My_New_Repo
Creates a new note in the Zettelkasten repository. Notes can be created with only a title, or with both a title and a body. The ID generated is randomised.
Note Title Requirements:
- Can only contain alphanumeric characters (letters and numbers)
- Can be space-separated or a single word (e.g.,
My NoteorMyNote) - No special characters allowed (e.g., dashes, underscores, symbols)
- No emojis allowed in note titles
- Spaces in the title will be automatically converted to underscores in the filename
- Example:
My New NotebecomesMy_New_Note.txt - Example:
SimpleNotebecomesSimpleNote.txt
- Example:
Note Body:
- Emojis can be used in the note body, but be aware that if your terminal or text editor does not support emojis, they may appear as strange characters (e.g.,
??) - Ensure your editor and terminal have proper emoji support before using them in note content
Format:
new -t <TITLE> [-b <BODY>]
When you create a note with just a title and no -b flag, your default text editor will open automatically. The application will be blocked in the background until you close the editor (whether you save changes or not).
Example:
new -t New_Note
Expected Output:
Opening editor for note body...
Note body saved from editor.
Note created: New_Note.txt #e0e7b989
When you use the -b flag without providing a body argument, the note is created with an empty body. The text editor will NOT open.
Example:
new -t New_Note -b
Expected Output:
Note created: New_Note.txt #e0e7b989
When you provide both a title and a body argument, the note is created immediately with the specified body. The text editor will NOT open.
Example:
new -t New_Note -b "This is a new note"
Expected Output:
Note created: New_Note.txt #e0e7b989
Opens an editor to modify the body of an existing note. Editor is based on the default editor of your system, can be notepad, vim etc. The application is blocked in the background until the user closes the editor (be it after saving changes or not)
Format:
edit <note-id>
Example:
edit e0e7b989
Expected Output:
Opening editor for note body...
Note body saved from editor.
Successfully edited note: New_Note.txt, id: e0e7b989
Lists notes with precise filters for pinned and archived states.
• -p shows only pinned notes.
• -a shows only archived notes.
You can combine flags in any order; behavior is defined by this matrix:
list→ pinned = X, archived = 0 (all unarchived notes)list -a→ pinned = X, archived = 1 (all archived notes)list -p→ pinned = 1, archived = 0 (pinned and unarchived)list -p -a→ pinned = 1, archived = 1 (pinned and archived)
Format:
list [-p] [-a]
Use the command without flags.
Example:
list
Expected Output:
You have 3 notes:
1. New_Note.txt 2025-10-17 e0e7b989
2. brrr_againi.txt 2025-10-16 ccfd2e51
3. file.txt 2025-10-16 55bb2cac
Use the -a flag.
Example:
list -a
Expected Output:
You have 2 notes (archived):
1. Archived_Note.txt 2025-10-10 a1b2c3d4
2. Old_Research.txt 2025-10-08 a9f0e1d2
Use both -p and -a (in any order).
Example:
list -a -p
Expected Output:
You have 1 pinned and archived notes:
1. Archived_Note.txt 2025-10-10 a1b2c3d4
Use the -p flag without -a.
Example:
list -p
Expected Output:
You have 1 pinned notes:
1. file.txt 2025-10-16 55bb2cac
Removes the note at the specified index. Confirmation prevents accidental loss.
Format:
delete [-f] <NOTE_ID>
To delete with confirmation, use the command with no flags.
Example:
delete e0e7b989
Expected Output:
Confirm deletion on 'New_Note', noteID e0e7b989? (y/n)
> y
Note at e0e7b989 deleted
Use the command with the -f flag.
Example:
delete -f 55bb2cac
Expected Output:
Note at 55bb2cac deleted
Pins a note in the repository to keep it at the top of your list.
Format:
pin <NOTE_ID>
Example:
pin ccfd2e51
Expected Output:
Got it. I've pinned this note: ccfd2e51
Unpins a note in the repository.
Format:
unpin <NOTE_ID>
Example:
unpin ccfd2e51
Expected Output:
Got it. I've unpinned this note: ccfd2e51
Moves a note to the archive folder. There will be an archive folder for each of the repositories.
Archived notes can still be viewed using list -a.
Format:
archive <note-id>
Example:
archive e0e7b989
Expected Output:
Archived note: archive/New_Note.txt
Moves a note out of the archive folder back to the main notes directory.
Format:
unarchive <note-id>
Example:
unarchive e0e7b989
Expected Output:
Unarchived note: New_Note.txt (moved to notes/)
Prints the full body of a note by its ID. Note ID must be 8 lowercase hexadecimal characters.
Format:
print-body <NOTE_ID>
Example:
print-body abcd1234
Expected Output:
Body of note #abcd1234:
Hello World
Searches for notes that contain the specified text in their body.
Format:
find <text>
Example:
find "Zettelkasten"
Expected Output:
Here are the matching notes in your list:
1. New_Note.txt 2025-10-17 e0e7b989
2. Research.txt 2025-10-15 a1b2c3d4
ZettelCLI uses a global tagging system that allows you to organize notes across all repositories. Tags are created globally and can be used by any repository and any note.
Tag Naming Requirements:
- Can only contain alphanumeric characters (letters and numbers)
- Can include dashes (
-) to separate words - No spaces allowed
- No special characters other than dashes (e.g.,
?,%,!,_are not allowed) - Examples:
- Allowed:
important,work-notes,123-456-abc,project2024 - Not allowed:
my tag(contains space),urgent!!(contains!),test_tag(contains_)
- Allowed:
Creates a new global tag that is not initially linked to any note. This tag becomes available for use across all repositories.
Format:
new-tag <tag-name>
Example:
new-tag important
Expected Output:
Tag 'important' has been added.
Assigns a tag to a specific note. If the tag does not exist globally, it will be created automatically and then assigned to the note.
Format:
add-tag <note-id> <tag-name>
Example:
add-tag e0e7b989 important
Expected Output:
Note #e0e7b989 has been tagged with 'important'
Displays all global tags that have been created across all repositories.
Format:
list-tags-all
Expected Output:
You have 3 tags:
1. 'important'
2. 'research'
3. 'todo'
Shows all tags assigned to a specific note.
Format:
list-tags <note-id>
Example:
list-tags e0e7b989
Expected Output:
Tags for note #e0e7b989:
1. important
2. research
Removes a tag from a specific note without deleting the tag globally. The tag remains available for other notes.
Format:
delete-tag [-f] <note-id> <tag>
Example (with confirmation):
delete-tag e0e7b989 important
Expected Output:
Confirm deletion of tag 'important' on note # 'e0e7b989'? (y/n)
> y
Tag 'important' has been deleted from note #e0e7b989.
Example (without confirmation):
delete-tag -f e0e7b989 important
Expected Output:
Tag 'important' has been deleted from note #e0e7b989.
Deletes a tag from all notes across all repositories and removes it from the global tag list.
Format:
delete-tag-globally [-f] <tag>
Example (with confirmation):
delete-tag-globally important
Expected Output:
Confirm deletion of tag 'important'? (y/n)
> y
Tag 'important' has been deleted across all notes, globally.
Example (without confirmation):
delete-tag-globally -f important
Expected Output:
Tag 'important' has been deleted across all notes, globally.
Renames a tag globally across all notes in all repositories.
Format:
rename-tag <old-tag> <new-tag>
Example:
rename-tag important critical
Expected Output:
Tag 'important' has been renamed to 'critical' across all notes. All affected notes have been updated.
ZettelCLI allows you to create directional links between notes to build a knowledge graph. Links can be one-way or bidirectional.
Creates a one-way link from a source note to a target note, establishing the relationship: source → target.
Format:
link <source-id> <target-id>
Example:
link e0e7b989 ccfd2e51
This creates the relationship: e0e7b989 → ccfd2e51
Expected Output:
Note 'New_Note' now links to note 'brrr_againi'.
Removes a one-way link from source to target. This destroys the source → target relationship if it exists.
Format:
unlink <source-id> <target-id>
Example:
unlink e0e7b989 ccfd2e51
This removes the relationship: e0e7b989 → ccfd2e51
Expected Output:
The link from note #e0e7b989 to note #ccfd2e51 has been removed.
Creates links in both directions between two notes, establishing the relationships: id1 → id2 and id2 → id1.
Format:
link-both <id1> <id2>
Example:
link-both e0e7b989 ccfd2e51
This creates the relationships: e0e7b989 → ccfd2e51 and ccfd2e51 → e0e7b989
Expected Output:
Notes 'New_Note' and 'brrr_againi' are now linked in both directions.
Removes all links between two notes in both directions. This destroys both the id1 → id2 and id2 → id1 relationships.
Format:
unlink-both <id1> <id2>
Example:
unlink-both e0e7b989 ccfd2e51
This removes the relationships: e0e7b989 → ccfd2e51 and ccfd2e51 → e0e7b989
Expected Output:
All links between note #e0e7b989 and note #ccfd2e51 have been removed.
Shows all notes that link to the specified note (incoming links).
Format:
list-incoming-links <note-id>
Example:
list-incoming-links ccfd2e51
Expected Output:
Here are the notes that link to note #ccfd2e51 (incoming):
1. New_Note.txt 2025-10-17 e0e7b989
Shows all notes that the specified note links to (outgoing links).
Format:
list-outgoing-links <note-id>
Example:
list-outgoing-links e0e7b989
Expected Output:
Here are the notes that note #e0e7b989 links to (outgoing):
1. brrr_againi.txt 2025-10-16 ccfd2e51
Displays a complete list of available commands and their descriptions.
Format:
help
Expected Output:
Available Commands:
init <repo-name> - Initialize a new repository
change-repo[pository] <repo-name> - Switch to another existing repository
current-repo[pository] - Show the name of the current repository
new -t <title> [-b <body>] - Create a new note
edit <note-id> - Edit an existing note
list [-p] [-a] - List notes (pinned and/or archived filters)
delete [-f] <note-id> - Delete a note by ID
pin <note-id> - Pin a note
unpin <note-id> - Unpin a note
new-tag <tag-name> - Adds a tag
add-tag <note-id> <tag-name> - Tag a note
link <source-id> <target-id> - Link two notes
unlink <source-id> <target-id> - Unlink two notes
link-both <id1> <id2> - Link two notes in both directions
unlink-both <id1> <id2> - Unlink two notes in both directions
list-incoming-links <note-id> - Show incoming linked notes
list-outgoing-links <note-id> - Show outgoing linked notes
list-tags-all - Lists all tags that exist globally
list-tags <note-id> - List tags for an single note
delete-tag [-f] <note-id> <tag> - Delete a tag from a note
delete-tag-globally [-f] <tag> - Delete a tag from all notes
rename-tag <old-tag> <new-tag> - Rename a tag globally
archive <note-id> - Moves note to archive folder
unarchive <note-id> - Moves note out of archive folder
print-body <note-id> - Print the body of a note
find <text> - Search for notes
help - Show this list of commands
bye - Exit the application
Exits ZettelCLI and saves all changes.
Format:
bye
Expected Output:
Bye. Hope to see you again soon!