Skip to content

Add SnipCommand importer tool + move snips between CLIs#34

Merged
StuartMeeks merged 1 commit into
mainfrom
feat/importer-snipcommand
Jun 1, 2026
Merged

Add SnipCommand importer tool + move snips between CLIs#34
StuartMeeks merged 1 commit into
mainfrom
feat/importer-snipcommand

Conversation

@StuartMeeks

Copy link
Copy Markdown
Owner

What

Implements the Importer backlog item from TODO.md: a cross-platform .NET console tool, snipdeck-importer, that brings command snippets in from SnipCommand — plus two supporting changes that fell naturally out of it.

1. tools/Snipdeck.Importer — the importer tool

  • snipdeck-importer snipcommand <path> (Spectre.Console.Cli). Dry-run by default; --write is the only path that mutates a store.
  • Options: --store, --write, --cli (force a CLI), --into (fallback CLI for unconfident suggestions), --allow-duplicates.
  • On --write: backs the store up first (honouring the desktop app's retention), mints fresh GUIDs, creates CLIs on demand, and skips duplicates — then warns to restart Snipdeck.

Format finding: despite the .db extension, a SnipCommand export is pretty-printed JSON, not SQLite — so it's parsed with System.Text.Json (no new dependency). The ISnippetSource adapter still header-sniffs so a real-SQLite source could slot in later.

Pure, unit-tested pieces:

  • ScMarkupTranslator[sc_choice]/[sc_variable]{token} + structured Parameter[]; slugifies names with spaces/punctuation ("Agreement ID"AgreementID), disambiguates collisions, sanitises untrusted input, leaves malformed markup verbatim.
  • CliSuggester — CLI from the first token, peeling launcher wrappers (sudo/npx) but not runtimes (pip).
  • StoreMerger — pure Plan + Apply; CLI-scoped de-duplication by (CLI, Title, CommandTemplate).

2. Core: shared paths + tag parsing

  • DefaultPaths centralises the data-path layout so the tool resolves the same store/backup locations as the app; WindowsPathProvider now delegates (behaviour unchanged).
  • TagParser shares tag-CSV normalisation between the snip editor and the importer.

3. App: move a snip to a different CLI

The snip editor gains a CLI selector (the editor already received the CLI list — it was just unused). Re-homes a snip on save; pairs with the importer's --into fallback.

4. First-run seed

A snipdeck-importer CLI now sits alongside Examples, with snips demonstrating the importer's own commands.

Also

  • Bumped Velopack 1.0.1 → 1.1.1 (the only stale package; the other 13 were already current).
  • Added an Ubuntu importer-tests CI job.
  • Docs: importer README + repo README pointer + CHANGELOG.

Testing

  • Core: 213 tests pass. Importer: 47 tests pass (translator, suggester, merger, JSON source against a trimmed real-export fixture). Both run on Linux.
  • E2E against a real SnipCommand export: dry-run lists 25 snips across mpt-app/pip/inv-app; --write creates the store + a backup; re-run skips all 25 as duplicates; --allow-duplicates re-imports.
  • WinUI App head compile-verified on Windows (XAML CLI selector, interactions/path-provider changes, Velopack bump): 0 warnings, 0 errors.
  • A medium-effort code review pass was run; its findings (uncaught retention crash, cross-CLI dedupe, dead CrossPlatformPathProvider, duplicated tag parsing) are addressed in this PR.

🤖 Generated with Claude Code

Introduce `tools/Snipdeck.Importer`, a cross-platform .NET console tool
(`snipdeck-importer`) that imports command snippets from a SnipCommand export
into a Snipdeck store. SnipCommand's export is JSON despite its `.db`
extension, so it is parsed with System.Text.Json — no SQLite dependency.

Importer:
- `snipcommand <path>` subcommand (Spectre.Console.Cli), dry-run by default;
  `--write` backs the store up, mints fresh ids, creates CLIs on demand and
  skips duplicates. `--store`/`--cli`/`--into`/`--allow-duplicates` control it.
- `ISnippetSource` isolates format parsing; `ScMarkupTranslator` converts
  `[sc_choice]`/`[sc_variable]` markup into `{token}` placeholders + structured
  parameters (slugifying names, disambiguating collisions, defensively
  sanitising untrusted input); `CliSuggester` derives the CLI from the first
  token; `StoreMerger` plans/applies the merge with CLI-scoped de-duplication.

Core:
- Factor the data-path layout into `DefaultPaths` so the tool resolves the same
  store/backup locations the desktop app uses; `WindowsPathProvider` now
  delegates to it (behaviour unchanged).
- Share tag-list normalisation via `TagParser`, used by the snip editor and the
  importer.

App:
- Snip editor gains a CLI selector, so a snip can be re-homed to a different
  CLI — pairs with the importer's `--into` fallback.

Seed: a first-run `snipdeck-importer` CLI sits alongside Examples, with snips
that demonstrate the importer's own commands.

Also: bump Velopack 1.0.1 -> 1.1.1 (latest stable; the rest were current),
add an Ubuntu importer-tests CI job, and document the tool in its README plus
the repo README and CHANGELOG.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@StuartMeeks StuartMeeks merged commit 4f4c682 into main Jun 1, 2026
6 checks passed
@StuartMeeks StuartMeeks deleted the feat/importer-snipcommand branch June 1, 2026 04:16
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