Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@
"@sveltejs/kit": "^2.20.8",
"svelte": "^5.28.2",
"vite": "^6.3.5"
},
"devDependencies": {
"mdsvex": "^0.12.7"
}
}
21 changes: 19 additions & 2 deletions docs/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ aside nav {
display: flex;
flex-direction: column;
height: auto;
max-width: none;
margin: 0;
padding: 0;
}

.sidebar-section {
Expand Down Expand Up @@ -297,17 +300,31 @@ main {
@media (min-width: 769px) {
aside {
transform: translateX(0);
position: sticky;
position: fixed;
left: 0;
top: var(--header-height);
height: calc(100vh - var(--header-height));
z-index: 50;
}

.sidebar-overlay {
display: none !important;
}

.layout {
max-width: none;
margin: 0;
padding-left: var(--sidebar-width);
}

main {
margin-left: var(--sidebar-width);
margin-left: 0;
}

nav {
max-width: none;
margin: 0;
padding-left: var(--sidebar-width);
}
}

Expand Down
25 changes: 25 additions & 0 deletions docs/src/lib/layouts/MarkdownLayout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script lang="ts">
let {
children,
title = "subtrack",
description = "",
}: {
children: import("svelte").Snippet
title?: string
description?: string
} = $props()
</script>

<svelte:head>
<title>{title === "subtrack" ? "subtrack" : `${title} — subtrack`}</title>
{#if description}
<meta name="description" content={description} />
{/if}
</svelte:head>

<div class="docs">
{#if title !== "subtrack"}
<h1>{title}</h1>
{/if}
{@render children()}
</div>
1 change: 1 addition & 0 deletions docs/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
title: "Guides",
items: [
{ href: "/guides", label: "Usage Guides" },
{ href: "/tui", label: "Interactive TUI" },
{ href: "/data", label: "Data & Storage" },
{ href: "/configuration", label: "Configuration" },
],
Expand Down
142 changes: 142 additions & 0 deletions docs/src/routes/commands/+page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
title: Commands
description: Full reference for all subtrack CLI commands.
---

subtrack provides six commands. Most support both interactive and non-interactive modes.

## `list`

Lists all subscriptions in a formatted table. Subscriptions are grouped by currency by default, with a subtotal row per group.

| Option | Description |
|--------|-------------|
| `-c, --currency <C>` | Convert all prices to the given currency using live exchange rates |

### Examples

```bash
# List all subscriptions (grouped by currency)
subtrack list

# Convert all prices to JPY
subtrack list --currency JPY
```

When `--currency` is used, all prices are converted to the target currency (fetched from [open.er-api.com](https://open.er-api.com)) and displayed as a single group with a grand total.

## `add`

Adds a new subscription. Without flags, prompts for all fields interactively. Providing all flags skips prompts entirely (useful for scripts).

| Option | Description |
|--------|-------------|
| `--name <name>` | Subscription name (max 100 characters) |
| `--price <price>` | Payment amount — integer, non-negative, max 99,999,999 |
| `--currency <C>` | Currency code. Supported: JPY, USD, EUR, GBP, AUD, CAD, KRW, CNY, SGD, HKD |
| `--cycle <cycle>` | Billing cycle. One of: weekly, bi-weekly, monthly, quarterly, semi-annual, yearly |
| `--tags <tags>` | Comma-separated tags (max 10 tags, each max 50 characters) |

### Examples

```bash
# Interactive mode
subtrack add

# Fully non-interactive (skips confirmation)
subtrack add \
--name Spotify \
--price 980 \
--currency JPY \
--cycle monthly \
--tags music

# Partial flags — missing fields are prompted
subtrack add --name Netflix

# Tags with existing tag autocomplete
subtrack add --name "AWS" --price 50 --currency USD --cycle monthly
```

## `delete`

Shows an interactive checkbox list of all subscriptions. Select one or more to delete. Confirmation is required before deletion.

<div class="callout warning">
<strong>⚠ Note:</strong> The <code>delete</code> command is always interactive. There is no non-interactive mode.
</div>

### Example

```bash
subtrack delete
```

## `payment [period]`

Calculates and displays how much you pay over a given billing period. All subscriptions are automatically converted to the target period based on their billing cycle.

The `period` argument defaults to `monthly`. Valid values:

| Period | Alias |
|--------|-------|
| `weekly` | per week |
| `bi-weekly` | per two weeks |
| `monthly` | per month (default) |
| `quarterly` | per 3 months |
| `semi-annual` | per 6 months |
| `yearly` | per year |

| Option | Description |
|--------|-------------|
| `-c, --currency <C>` | Convert all prices to the given currency using live exchange rates |

### Examples

```bash
# Monthly total (default)
subtrack payment

# Yearly total
subtrack payment yearly

# Weekly total in JPY
subtrack payment weekly --currency JPY
```

When `--currency` is used, the total is displayed as a single amount in the target currency. Without it, totals are grouped by currency.

If exchange rates cannot be fetched (e.g. offline), the command falls back to per-currency display without conversion.

## `tags <taglist...>`

Filters and displays subscriptions that have **all** specified tags (AND logic).

### Examples

```bash
# Subscriptions tagged with "music"
subtrack tags music

# Subscriptions tagged with both "music" AND "video"
subtrack tags music video

# Subscriptions tagged with "entertainment", "video", and "kids"
subtrack tags entertainment video kids
```

## `backup <destination>`

Creates a timestamped backup of the SQLite database in the specified directory. The backup filename follows the format `subtrack_YYYYMMDD_HHmmss.db`.

If the destination does not exist or is not a directory, the command exits with an error. The backup will not overwrite existing files (exclusive create).

### Examples

```bash
# Backup to current directory
subtrack backup .

# Backup to ~/backups
subtrack backup ~/backups
```
Loading