Skip to content

appsoftwareltd/as-notes

Repository files navigation

AS Notes

AS Notes is a VS Code extension that turns your editor into a Personal Knowledge Management System (PKMS).

(Click for 1 minute Youtube video demo)

AS Notes demo

Main Features

  • Privacy focused - does not send your data anywhere
  • Version control friendly (e.g. Git)
  • Lightweight indexing of your notes (local sqlite3 WASM)
  • Automatic wikilink / file rename tracking

Wikilinks

  • Logseq / Roam / Obsidian style [[wikilinks]] with nested link support e.g. [[[[AS Notes]] Page]]
  • Links resolve to the target page anywhere in your workspace
  • Renaming a link updates the target file and all matching references across the workspace

AS Notes backlinks wikilinks

Task Management

Toggle markdown TODOs with a keyboard shortcut:

- [ ] Marker for todo added
- [x] Marker for todo marked done
Marker for todo removed

Ctrl+Shift+Enter (Windows/Linux) / Cmd+Shift+Enter (macOS). Keybinding is configurable.

AS Notes todo panel

Note: Todo toggling requires an initialised workspace (.asnotes/ directory). See Getting started.

Backlinks Panel

Ctrl+Alt+B (Windows/Linux) / Cmd+Alt+B (macOS)

AS Notes backlinks panel

Daily Journal

Press Ctrl+Alt+J (Cmd+Alt+J on macOS) to create or open today's daily journal page.

Journal files are created as YYYY_MM_DD.md in a dedicated journals/ folder (configurable). New pages are generated from a journal_template.md template — edit it to add your own sections and prompts. The YYYY-MM-DD placeholder in the template is replaced with today's date on creation.

Note: Daily journal requires an initialised workspace (.asnotes/ directory). See Getting started.

Compatibility With Other Markdown PKMS

AS Notes can work with knowledge bases created in Obsidian or Logseq due to similar file structures. There are format differences — Obsidian does not support nested wikilinks, and AS Notes does not use a block structure like Logseq. Front matter in AS Notes uses YAML.

AS Notes Pro

A Pro licence unlocks premium features. Enter your licence key in VS Code settings under as-notes.licenceKey. When a valid key is active the status bar shows AS Notes (Pro).

Encrypted notes

Pro users can store sensitive notes in encrypted files. Any file with the .enc.md extension is treated as an encrypted note — it is excluded from the search index and never read as plain text by the extension.

Getting started with encryption:

  1. Run AS Notes: Set Encryption Key from the Command Palette. Your passphrase is stored securely in the OS keychain (VS Code SecretStorage) — it is never written to disk or settings files.
  2. Create an encrypted note with AS Notes: Create Encrypted Note (or AS Notes: Create Encrypted Journal Note for a dated journal entry).
  3. Write your note in the editor. When you want to lock it, run AS Notes: Encrypt All Notes — all plaintext .enc.md files will be encrypted in place.
  4. To read a note, run AS Notes: Decrypt All Notes — files are decrypted in place using your stored passphrase.

Encryption details:

  • Algorithm: AES-256-GCM with a per-encryption random 12-byte nonce
  • Key derivation: PBKDF2-SHA256 (100,000 iterations) from your passphrase
  • File format: a single-line ASNOTES_ENC_V1:<base64url payload> marker — easily detectable by tooling
  • A git pre-commit hook is automatically installed at .git/hooks/pre-commit to prevent accidentally committing an unencrypted .enc.md file. The hook is self-updating — if AS Notes detects a stale version it replaces it automatically on the next Rebuild Index or periodic scan. If a commit is unexpectedly blocked, run AS Notes: Encrypt All Notes first.

Commands:

  • AS Notes: Set Encryption Key — save passphrase to OS keychain
  • AS Notes: Clear Encryption Key — remove the stored passphrase
  • AS Notes: Encrypt All Notes — encrypt all plaintext .enc.md files
  • AS Notes: Decrypt All Notes — decrypt all encrypted .enc.md files
  • AS Notes: Create Encrypted Note — create a new named .enc.md file
  • AS Notes: Create Encrypted Journal Note — create today's journal entry as .enc.md
  • AS Notes: Encrypt Current Note — encrypt the active .enc.md file (reads unsaved editor content)
  • AS Notes: Decrypt Current Note — decrypt the active .enc.md file (reads from disk)

Planned Pro features:

  • HTML/wiki export
  • UI password lock

To obtain a licence key, contact appsoftware.com.

VS Code Marketplace

https://marketplace.visualstudio.com/items?itemName=appsoftwareltd.as-notes

Getting started

For a sample knowledge base, clone https://github.com/appsoftwareltd/as-notes-demo-notes and follow the instructions there to initialise.

Initialise a workspace

AS Notes activates when it finds a .asnotes/ directory in your workspace root (similar to .git/ or .obsidian/). Without it, the extension runs in passive mode — you'll see a status bar item inviting you to initialise.

To initialise:

  1. Open the Command Palette (Ctrl+Shift+P)
  2. Run AS Notes: Initialise Workspace

This creates the .asnotes/ directory, builds a SQLite index of all markdown files, and activates all features. The index file (.asnotes/index.db) is excluded from git by an auto-generated .gitignore.

Rebuild the index

If the index becomes stale or corrupted, run AS Notes: Rebuild Index from the Command Palette. This drops and recreates the entire index with a progress indicator.

Features

Wikilink highlighting

Every [[wikilink]] in a markdown file is highlighted in blue. When your cursor is inside a link, that specific link is highlighted with a brighter blue, bold, and underlined — so you always know which link you're about to interact with.

Nested wikilinks

Links can contain other links:

[[Specific [[Topic]] Details]]
[[Specific [[[[Topic]] Variant]] Details]]

This creates three navigable targets:

You click on... You navigate to...
[[Topic]] Topic.md
[[Specific or Details]] (the outer portions) Specific [[Topic]] Details.md
[[[[Topic]] Variant]] (the outer portions) [[Topic]] Variant.md

Nesting works to arbitrary depth. The extension always identifies the innermost link under your cursor for highlighting, hover, and click targets.

Click navigation

Ctrl+Click (Cmd+Click on macOS) on any wikilink to open the target .md file. Links resolve globally across the workspace (see Subfolder link resolution).

Auto-create missing pages

Navigating to a page that doesn't exist creates it automatically, so you can write forward-references before the target page exists.

Hover tooltips

Hover over any wikilink to see:

  • The target filename (e.g. My Page.md)
  • Whether the file already exists or will be created on click
  • The number of backlinks (other pages that link to this target)

Link rename synchronisation

When you edit a wikilink's text and move your cursor away (or switch files), AS Notes detects the change and offers to:

  1. Rename the corresponding .md file (if it exists)
  2. Update every matching link across all markdown files in the workspace

A single confirmation dialog covers all affected nesting levels. For example, editing [[Inner]] inside [[Outer [[Inner]] text]] offers to rename both the inner and outer pages.

You can decline — the link text change is kept but files and other links are left untouched.

Case-insensitive file matching

[[my page]] resolves to My Page.md regardless of OS. On case-sensitive filesystems (Linux), a directory scan finds the match. On Windows and macOS the filesystem handles it natively.

Filename sanitisation

Invalid filename characters (/ ? < > \ : * | ") are replaced with _:

[[What is 1/2 + 1/4?]]  →  What is 1_2 + 1_4_.md

Page aliases

Define alternative names for a page using YAML front matter at the top of any markdown file:

---
aliases:
  - Short Name
  - Another Name
---

Or inline array style:

---
aliases: [Short Name, Another Name]
---

Linking to [[Short Name]] or [[Another Name]] navigates to the page that declares those aliases — no extra file is created.

  • Hover tooltips show alias resolution: Short Name.md → ActualPage.md
  • Rename tracking is alias-aware — editing an alias link offers to update front matter and all matching references
  • Backlink counts include both direct and alias references
  • Alias values are plain strings; accidental [[ / ]] brackets are stripped automatically

Subfolder link resolution

Wikilinks resolve globally across the workspace, not just in the current directory. The extension uses the persistent index to find matching files anywhere in the folder tree.

Resolution order:

  1. Direct filename match[[My Page]] finds My Page.md anywhere in the workspace
  2. Alias match — if no file matches, check page aliases
  3. Auto-create — if nothing matches, create the file in the same directory as the source

Disambiguation — when multiple files share the same name (e.g. notes/Topic.md and archive/Topic.md):

  1. A file in the same directory as the source always wins
  2. Otherwise, the closest folder is preferred (measured by directory distance)

Wikilink autocomplete

Type [[ in any markdown file to trigger autocomplete, listing all indexed pages and aliases. The list filters as you type.

  • Page suggestions show the page name (without .md), with folder paths for disambiguation when names collide
  • Alias suggestions show the alias with an arrow to the canonical page (e.g. → ActualPage)
  • Auto-close — selecting a suggestion inserts the name and appends ]]
  • Nested wikilinks[[ inside an unclosed [[... starts a new autocompletion for the inner link
  • Completions are suppressed inside front matter blocks

Persistent index

AS Notes maintains a SQLite database (.asnotes/index.db) that indexes all markdown files in the workspace. The index tracks:

  • Pages — file paths, filenames, titles (extracted from the first # heading)
  • Links — every wikilink in every file, with line, column, nesting depth, and parent references
  • Aliases — alternative names declared in YAML front matter, with sanitised filenames
  • Backlinks — reverse lookups for hover tooltips (including alias references)

The index is kept up-to-date automatically:

  • On file save, create, delete, or rename
  • On editor switch (captures unsaved edits)
  • Via a configurable periodic background scan

Todo toggle

Press Ctrl+Shift+Enter (Cmd+Shift+Enter on macOS) on any line in a markdown file to cycle through todo states:

Current state After toggle
buy milk - [ ] buy milk
- [ ] buy milk - [x] buy milk
- [x] buy milk buy milk
  • List-aware: - some text becomes - [ ] some text (no re-wrapping)
  • Indentation preserved: works correctly on indented/nested lines
  • Multi-cursor: each cursor's line is toggled independently
  • Configurable keybinding: search for "AS Notes: Toggle Todo" in Keyboard Shortcuts (Ctrl+K Ctrl+S)

Tasks panel

The AS Notes Tasks panel appears in the Explorer sidebar when the workspace is initialised. It provides a tree view of all todo items across your markdown files, grouped by page.

  • Show TODO only (default: on) — filters the list to show only unchecked (- [ ]) tasks. Toggle this with the filter icon in the panel title bar or via the AS Notes: Toggle Show TODO Only command.
  • Click to navigate — clicking a task opens the file and scrolls to the exact line.
  • Inline toggle — each task has a check button that toggles its done/todo state directly from the panel, without stealing focus from your active editor.
  • Keyboard shortcut — press Ctrl+Alt+T (Cmd+Alt+T on macOS) to toggle the task panel's visibility.
  • Live sync — the panel refreshes automatically on file save, edit, create, delete, rename, todo toggle, and periodic background scans.

Backlinks panel

The Backlinks panel shows all incoming links to the active markdown file. Open it with Ctrl+Alt+B (Cmd+Alt+B on macOS), or click the references icon in the editor title bar.

  • Rich context — each backlink shows the surrounding line with the wikilink highlighted.
  • Grouped by page — organised by source file with page title and path.
  • Click to navigate — click any backlink entry to jump directly to the source file and line.
  • Alias-aware — includes links that target the page via its aliases, not just direct filename references.
  • Live sync — the panel auto-updates when you switch files, save, or when the index changes.
  • Editor-side display — opens beside your active editor (like Markdown Preview), giving you a spacious view of backlink context.

Daily journal

Press Ctrl+Alt+J (Cmd+Alt+J on macOS) to create or open today's daily journal. The extension creates a dated markdown file in a dedicated journal folder — one file per day.

  • Filename format: YYYY_MM_DD.md (e.g. 2026_03_02.md)
  • Journal folder: defaults to journals/ (configurable via as-notes.journalFolder)
  • Template-based: new files are created from journal_template.md, with YYYY-MM-DD replaced by the current date. Edit the template to customise future pages.
  • Auto-setup: the journal folder and default template are created on first use
  • Instant indexing: new journal files are indexed immediately for wikilink completion and backlinks
  • Idempotent: pressing the shortcut again on the same day opens the existing file

Settings

Setting Default Description
as-notes.periodicScanInterval 300 Seconds between automatic background scans for file changes. Set to 0 to disable. Minimum: 30.
as-notes.journalFolder journals Folder for daily journal files, relative to workspace root.
as-notes.licenceKey (empty) AS Notes Pro licence key. Scope: machine (not synced).

Supported file types

The extension activates for files with .md and .markdown extensions.

Wikilink syntax

A wikilink is any text enclosed in double square brackets:

See [[Page Name]] for details.

The text between the brackets becomes both the display text and the page name. The target file is Page Name.md in the same directory.

Nesting rules

Wikilinks can be nested by adding more bracket pairs:

[[Outer [[Inner]] text]]

The parser uses a stack-based bracket matching algorithm. Each pair of [[ and ]] that balances correctly forms a valid wikilink. See docs/TECHNICAL.md for a detailed explanation of the parsing algorithm and edge cases.

Development

# Install dependencies
npm install

# Build the extension
npm run build

# Watch mode (rebuilds on changes)
npm run watch

# Run unit tests
npm test

# Type-check
npm run lint

Debugging

Press F5 in VS Code to launch the Extension Development Host with the extension loaded.

The debug version takes precedence over the marketplace install, so both can coexist.

VS Code remembers the last folder opened in the Extension Development Host. The demo knowledge base is designed to cover common usage scenarios.

Testing

Unit tests use vitest and cover the wikilink parser, offset-based lookup, segment computation, index service CRUD, title extraction, rename detection data flow, and nested link indexing. Run with npm test.

Architecture

File Purpose
src/extension.ts Entry point — activation model (passive/full mode), commands, index triggers
src/Wikilink.ts Model class — positions, page name, filename sanitisation
src/WikilinkService.ts Stack-based parser, innermost-offset lookup, segment computation
src/WikilinkDecorationManager.ts Editor decorations (default + active highlight)
src/WikilinkDocumentLinkProvider.ts Ctrl+Click navigation via non-overlapping segments (alias-aware tooltips)
src/WikilinkHoverProvider.ts Hover tooltips with target file existence, alias indicator, backlink count
src/WikilinkFileService.ts File resolution — index-aware global matching, alias resolution, subfolder disambiguation
src/WikilinkRenameTracker.ts Rename detection (index-backed), alias vs direct rename classification, workspace-wide updates
src/WikilinkCompletionProvider.ts Wikilink autocomplete — [[ trigger, page + alias suggestions, auto-close, nested link support
src/CompletionUtils.ts Pure utilities for completion logic — bracket detection, front matter detection
src/IndexService.ts SQLite data layer — schema, CRUD, content indexing, alias management, task indexing, nesting detection
src/IndexScanner.ts VS Code filesystem scanning — file indexing, full scan, stale scan
src/FrontMatterService.ts Lightweight YAML front matter parser — alias extraction, in-place alias updates
src/PathUtils.ts Pure utilities — path distance calculation, filename sanitisation
src/TodoToggleService.ts Pure todo toggle logic — three-state cycle (plain / unchecked / done)
src/TaskPanelProvider.ts Explorer tree view — task list grouped by page, todo-only filter, click-to-navigate
src/BacklinkPanelProvider.ts Webview panel — backlinks display with context, grouped by source page, click-to-navigate
src/JournalService.ts Pure journal logic — date formatting, template processing, path construction
src/LicenceService.ts Pure licence key validation logic — no VS Code imports
src/LicenceActivationService.ts Licence activation stub — SecretStorage token management, server call placeholder
build.mjs Custom esbuild script — bundles extension, copies WASM binary
src/test/ Unit tests (vitest)

For a deep dive into the technical design, see docs/TECHNICAL.md.

Publishing

Releases are published to the VS Code Marketplace manually, then a GitHub Release is created automatically when a version tag is pushed.

Step 1 — bump the version

Update version in package.json and add an entry to CHANGELOG.md.

Step 2 — publish to the VS Code Marketplace

npm run build
npx @vscode/vsce package
npx @vscode/vsce login appsoftwareltd   # enter PAT token if auth expired
npx @vscode/vsce publish

Step 3 — tag and push

git add package.json CHANGELOG.md README.md
git commit -m "Release v1.x.x"   # change version
git tag v1.x.x                   # change version
git push origin main --tags

Pushing the tag triggers the Release workflow, which creates a GitHub Release automatically with auto-generated release notes and the VS Code Marketplace install link.

Disclaimer

This software is provided "as is", without warranty of any kind, express or implied. The authors and contributors accept no responsibility or liability for any loss, corruption, or damage to data, files, or systems arising from the use or misuse of this extension, including but not limited to operations that create, rename, move, or modify files in your workspace.

You are solely responsible for maintaining backups of your data. It is strongly recommended to use version control (e.g. git) or another backup strategy for any notes or files you manage with this extension.

This extension is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License (CC BY-NC-SA 4.0).

You are free to use, share, and adapt this extension for non-commercial purposes with attribution. Commercial use requires a separate commercial license. See LICENSE for full terms or contact us https://www.appsoftware.com/contact.

About

A VS Code Notes / PKMS tool with wikilinks (including nested), task managment, daily journals and more

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages