@fredlackey/devutils 0.0.18 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +214 -141
- package/package.json +8 -83
- package/src/api/loader.js +229 -0
- package/src/api/registry.json +62 -0
- package/src/cli.js +293 -60
- package/src/commands/ai/index.js +16 -0
- package/src/commands/ai/launch.js +112 -0
- package/src/commands/ai/list.js +54 -0
- package/src/commands/ai/resume.js +70 -0
- package/src/commands/ai/sessions.js +121 -0
- package/src/commands/ai/set.js +131 -0
- package/src/commands/ai/show.js +74 -0
- package/src/commands/ai/tools.js +46 -0
- package/src/commands/alias/add.js +93 -0
- package/src/commands/alias/helpers.js +107 -0
- package/src/commands/alias/index.js +14 -0
- package/src/commands/alias/list.js +55 -0
- package/src/commands/alias/remove.js +62 -0
- package/src/commands/alias/sync.js +109 -0
- package/src/commands/api/disable.js +73 -0
- package/src/commands/api/enable.js +148 -0
- package/src/commands/api/index.js +15 -0
- package/src/commands/api/list.js +66 -0
- package/src/commands/api/update.js +87 -0
- package/src/commands/auth/index.js +15 -0
- package/src/commands/auth/list.js +49 -0
- package/src/commands/auth/login.js +384 -0
- package/src/commands/auth/logout.js +111 -0
- package/src/commands/auth/refresh.js +184 -0
- package/src/commands/auth/services.js +169 -0
- package/src/commands/auth/status.js +104 -0
- package/src/commands/config/export.js +224 -0
- package/src/commands/config/get.js +52 -0
- package/src/commands/config/import.js +308 -0
- package/src/commands/config/index.js +17 -0
- package/src/commands/config/init.js +143 -0
- package/src/commands/config/reset.js +57 -0
- package/src/commands/config/set.js +93 -0
- package/src/commands/config/show.js +35 -0
- package/src/commands/help.js +338 -0
- package/src/commands/identity/add.js +133 -0
- package/src/commands/identity/index.js +17 -0
- package/src/commands/identity/link.js +76 -0
- package/src/commands/identity/list.js +48 -0
- package/src/commands/identity/remove.js +72 -0
- package/src/commands/identity/show.js +65 -0
- package/src/commands/identity/sync.js +172 -0
- package/src/commands/identity/unlink.js +57 -0
- package/src/commands/ignore/add.js +165 -0
- package/src/commands/ignore/index.js +14 -0
- package/src/commands/ignore/list.js +89 -0
- package/src/commands/ignore/markers.js +43 -0
- package/src/commands/ignore/remove.js +164 -0
- package/src/commands/ignore/show.js +169 -0
- package/src/commands/machine/detect.js +122 -0
- package/src/commands/machine/index.js +14 -0
- package/src/commands/machine/list.js +74 -0
- package/src/commands/machine/set.js +106 -0
- package/src/commands/machine/show.js +35 -0
- package/src/commands/schema.js +152 -0
- package/src/commands/search/collections.js +134 -0
- package/src/commands/search/get.js +71 -0
- package/src/commands/search/index-cmd.js +54 -0
- package/src/commands/search/index.js +21 -0
- package/src/commands/search/keyword.js +60 -0
- package/src/commands/search/qmd.js +70 -0
- package/src/commands/search/query.js +64 -0
- package/src/commands/search/semantic.js +62 -0
- package/src/commands/search/status.js +46 -0
- package/src/commands/status.js +224 -171
- package/src/commands/tools/check.js +79 -0
- package/src/commands/tools/index.js +14 -0
- package/src/commands/tools/install.js +110 -0
- package/src/commands/tools/list.js +91 -0
- package/src/commands/tools/search.js +60 -0
- package/src/commands/update.js +83 -112
- package/src/commands/util/add.js +151 -0
- package/src/commands/util/index.js +15 -0
- package/src/commands/util/list.js +97 -0
- package/src/commands/util/remove.js +76 -0
- package/src/commands/util/run.js +79 -0
- package/src/commands/util/show.js +67 -0
- package/src/commands/version.js +21 -88
- package/src/installers/_template.js +104 -0
- package/src/installers/git.js +150 -0
- package/src/installers/homebrew.js +190 -0
- package/src/installers/node.js +223 -0
- package/src/installers/registry.json +29 -0
- package/src/lib/config.js +125 -0
- package/src/lib/detect.js +74 -0
- package/src/lib/errors.js +114 -0
- package/src/lib/github.js +315 -0
- package/src/lib/installer.js +225 -0
- package/src/lib/output.js +239 -0
- package/src/lib/platform.js +112 -0
- package/src/lib/platforms/amazon-linux.js +41 -0
- package/src/lib/platforms/gitbash.js +46 -0
- package/src/lib/platforms/macos.js +45 -0
- package/src/lib/platforms/raspbian.js +41 -0
- package/src/lib/platforms/ubuntu.js +39 -0
- package/src/lib/platforms/windows.js +45 -0
- package/src/lib/prompt.js +161 -0
- package/src/lib/schema.js +211 -0
- package/src/lib/shell.js +75 -0
- package/src/patterns/gitignore/claude-code.txt +25 -0
- package/src/patterns/gitignore/docker.txt +15 -0
- package/src/patterns/gitignore/go.txt +24 -0
- package/src/patterns/gitignore/java.txt +38 -0
- package/src/patterns/gitignore/jetbrains.txt +26 -0
- package/src/patterns/gitignore/linux.txt +18 -0
- package/src/patterns/gitignore/macos.txt +27 -0
- package/src/patterns/gitignore/node.txt +51 -0
- package/src/patterns/gitignore/python.txt +55 -0
- package/src/patterns/gitignore/rust.txt +14 -0
- package/src/patterns/gitignore/terraform.txt +30 -0
- package/src/patterns/gitignore/vscode.txt +15 -0
- package/src/patterns/gitignore/windows.txt +25 -0
- package/src/utils/clone/index.js +165 -0
- package/src/utils/git-push/index.js +230 -0
- package/src/utils/git-status/index.js +116 -0
- package/src/utils/git-status/unix.sh +75 -0
- package/src/utils/registry.json +41 -0
- package/bin/dev.js +0 -16
- package/files/README.md +0 -0
- package/files/claude/.claude/commands/setup-context.md +0 -3
- package/files/monorepos/_archive/README.md +0 -36
- package/files/monorepos/_legacy/README.md +0 -36
- package/files/monorepos/ai-docs/README.md +0 -33
- package/files/monorepos/apps/README.md +0 -24
- package/files/monorepos/docs/README.md +0 -40
- package/files/monorepos/packages/README.md +0 -25
- package/files/monorepos/research/README.md +0 -29
- package/files/monorepos/scripts/README.md +0 -24
- package/src/commands/README.md +0 -41
- package/src/commands/configure.js +0 -199
- package/src/commands/identity.js +0 -1630
- package/src/commands/ignore.js +0 -247
- package/src/commands/install.js +0 -526
- package/src/commands/setup.js +0 -246
- package/src/completion.js +0 -284
- package/src/constants.js +0 -45
- package/src/ignore/claude-code.txt +0 -10
- package/src/ignore/docker.txt +0 -18
- package/src/ignore/linux.txt +0 -23
- package/src/ignore/macos.txt +0 -36
- package/src/ignore/node.txt +0 -55
- package/src/ignore/terraform.txt +0 -37
- package/src/ignore/vscode.txt +0 -18
- package/src/ignore/windows.txt +0 -35
- package/src/index.js +0 -0
- package/src/installs/README.md +0 -399
- package/src/installs/adobe-creative-cloud.js +0 -546
- package/src/installs/adobe-creative-cloud.md +0 -605
- package/src/installs/appcleaner.js +0 -321
- package/src/installs/appcleaner.md +0 -699
- package/src/installs/apt-transport-https.js +0 -390
- package/src/installs/apt-transport-https.md +0 -678
- package/src/installs/atomicparsley.js +0 -642
- package/src/installs/atomicparsley.md +0 -795
- package/src/installs/aws-cli.js +0 -797
- package/src/installs/aws-cli.md +0 -727
- package/src/installs/balena-etcher.js +0 -710
- package/src/installs/balena-etcher.md +0 -761
- package/src/installs/bambu-studio.js +0 -1143
- package/src/installs/bambu-studio.md +0 -780
- package/src/installs/bash-completion.js +0 -575
- package/src/installs/bash-completion.md +0 -833
- package/src/installs/bash.js +0 -417
- package/src/installs/bash.md +0 -993
- package/src/installs/beyond-compare.js +0 -603
- package/src/installs/beyond-compare.md +0 -813
- package/src/installs/brave-browser.js +0 -968
- package/src/installs/brave-browser.md +0 -650
- package/src/installs/build-essential.js +0 -529
- package/src/installs/build-essential.md +0 -977
- package/src/installs/ca-certificates.js +0 -618
- package/src/installs/ca-certificates.md +0 -937
- package/src/installs/caffeine.js +0 -508
- package/src/installs/caffeine.md +0 -839
- package/src/installs/camtasia.js +0 -596
- package/src/installs/camtasia.md +0 -762
- package/src/installs/chatgpt.js +0 -476
- package/src/installs/chatgpt.md +0 -814
- package/src/installs/chocolatey.js +0 -456
- package/src/installs/chocolatey.md +0 -661
- package/src/installs/chrome-canary.js +0 -419
- package/src/installs/chrome-canary.md +0 -641
- package/src/installs/chromium.js +0 -667
- package/src/installs/chromium.md +0 -838
- package/src/installs/claude-code.js +0 -576
- package/src/installs/claude-code.md +0 -1173
- package/src/installs/cloudflare-warp.js +0 -900
- package/src/installs/cloudflare-warp.md +0 -1047
- package/src/installs/comet-browser.js +0 -588
- package/src/installs/comet-browser.md +0 -731
- package/src/installs/curl.js +0 -379
- package/src/installs/curl.md +0 -714
- package/src/installs/cursor.js +0 -579
- package/src/installs/cursor.md +0 -970
- package/src/installs/dbeaver.js +0 -924
- package/src/installs/dbeaver.md +0 -939
- package/src/installs/dbschema.js +0 -692
- package/src/installs/dbschema.md +0 -925
- package/src/installs/dependencies.md +0 -453
- package/src/installs/development-tools.js +0 -600
- package/src/installs/development-tools.md +0 -977
- package/src/installs/docker.js +0 -1029
- package/src/installs/docker.md +0 -1109
- package/src/installs/drawio.js +0 -1019
- package/src/installs/drawio.md +0 -795
- package/src/installs/elmedia-player.js +0 -347
- package/src/installs/elmedia-player.md +0 -556
- package/src/installs/ffmpeg.js +0 -889
- package/src/installs/ffmpeg.md +0 -852
- package/src/installs/file.js +0 -464
- package/src/installs/file.md +0 -987
- package/src/installs/gemini-cli.js +0 -811
- package/src/installs/gemini-cli.md +0 -1153
- package/src/installs/git.js +0 -400
- package/src/installs/git.md +0 -907
- package/src/installs/gitego.js +0 -949
- package/src/installs/gitego.md +0 -1172
- package/src/installs/go.js +0 -931
- package/src/installs/go.md +0 -958
- package/src/installs/google-antigravity.js +0 -913
- package/src/installs/google-antigravity.md +0 -1075
- package/src/installs/google-chrome.js +0 -833
- package/src/installs/google-chrome.md +0 -862
- package/src/installs/gpg.js +0 -480
- package/src/installs/gpg.md +0 -1056
- package/src/installs/homebrew.js +0 -1028
- package/src/installs/homebrew.md +0 -988
- package/src/installs/imageoptim.js +0 -968
- package/src/installs/imageoptim.md +0 -1119
- package/src/installs/installers.json +0 -4032
- package/src/installs/installers.json.tmp +0 -3953
- package/src/installs/jq.js +0 -400
- package/src/installs/jq.md +0 -809
- package/src/installs/keyboard-maestro.js +0 -719
- package/src/installs/keyboard-maestro.md +0 -825
- package/src/installs/kiro.js +0 -864
- package/src/installs/kiro.md +0 -1015
- package/src/installs/latex.js +0 -789
- package/src/installs/latex.md +0 -1095
- package/src/installs/lftp.js +0 -356
- package/src/installs/lftp.md +0 -907
- package/src/installs/lsb-release.js +0 -346
- package/src/installs/lsb-release.md +0 -814
- package/src/installs/messenger.js +0 -847
- package/src/installs/messenger.md +0 -900
- package/src/installs/microsoft-office.js +0 -568
- package/src/installs/microsoft-office.md +0 -760
- package/src/installs/microsoft-teams.js +0 -801
- package/src/installs/microsoft-teams.md +0 -886
- package/src/installs/moom.js +0 -326
- package/src/installs/moom.md +0 -570
- package/src/installs/node.js +0 -904
- package/src/installs/node.md +0 -1153
- package/src/installs/nordpass.js +0 -716
- package/src/installs/nordpass.md +0 -921
- package/src/installs/nordvpn.js +0 -892
- package/src/installs/nordvpn.md +0 -1052
- package/src/installs/nvm.js +0 -995
- package/src/installs/nvm.md +0 -1057
- package/src/installs/ohmyzsh.js +0 -529
- package/src/installs/ohmyzsh.md +0 -1094
- package/src/installs/openssh.js +0 -804
- package/src/installs/openssh.md +0 -1056
- package/src/installs/pandoc.js +0 -662
- package/src/installs/pandoc.md +0 -1036
- package/src/installs/parallels-desktop.js +0 -431
- package/src/installs/parallels-desktop.md +0 -446
- package/src/installs/pinentry.js +0 -510
- package/src/installs/pinentry.md +0 -1142
- package/src/installs/pngyu.js +0 -869
- package/src/installs/pngyu.md +0 -896
- package/src/installs/postman.js +0 -799
- package/src/installs/postman.md +0 -940
- package/src/installs/procps.js +0 -425
- package/src/installs/procps.md +0 -851
- package/src/installs/safari-tech-preview.js +0 -374
- package/src/installs/safari-tech-preview.md +0 -533
- package/src/installs/sfnt2woff.js +0 -658
- package/src/installs/sfnt2woff.md +0 -795
- package/src/installs/shellcheck.js +0 -481
- package/src/installs/shellcheck.md +0 -1005
- package/src/installs/slack.js +0 -741
- package/src/installs/slack.md +0 -865
- package/src/installs/snagit.js +0 -585
- package/src/installs/snagit.md +0 -844
- package/src/installs/software-properties-common.js +0 -372
- package/src/installs/software-properties-common.md +0 -805
- package/src/installs/spotify.js +0 -877
- package/src/installs/spotify.md +0 -901
- package/src/installs/studio-3t.js +0 -823
- package/src/installs/studio-3t.md +0 -918
- package/src/installs/sublime-text.js +0 -804
- package/src/installs/sublime-text.md +0 -914
- package/src/installs/superwhisper.js +0 -706
- package/src/installs/superwhisper.md +0 -630
- package/src/installs/tailscale.js +0 -745
- package/src/installs/tailscale.md +0 -1100
- package/src/installs/tar.js +0 -389
- package/src/installs/tar.md +0 -946
- package/src/installs/termius.js +0 -798
- package/src/installs/termius.md +0 -844
- package/src/installs/terraform.js +0 -779
- package/src/installs/terraform.md +0 -899
- package/src/installs/tfenv.js +0 -778
- package/src/installs/tfenv.md +0 -1091
- package/src/installs/tidal.js +0 -771
- package/src/installs/tidal.md +0 -864
- package/src/installs/tmux.js +0 -346
- package/src/installs/tmux.md +0 -1030
- package/src/installs/tree.js +0 -411
- package/src/installs/tree.md +0 -833
- package/src/installs/unzip.js +0 -460
- package/src/installs/unzip.md +0 -879
- package/src/installs/vim.js +0 -421
- package/src/installs/vim.md +0 -1040
- package/src/installs/vlc.js +0 -821
- package/src/installs/vlc.md +0 -927
- package/src/installs/vscode.js +0 -843
- package/src/installs/vscode.md +0 -1002
- package/src/installs/wget.js +0 -420
- package/src/installs/wget.md +0 -791
- package/src/installs/whatsapp.js +0 -729
- package/src/installs/whatsapp.md +0 -854
- package/src/installs/winpty.js +0 -352
- package/src/installs/winpty.md +0 -620
- package/src/installs/woff2.js +0 -553
- package/src/installs/woff2.md +0 -977
- package/src/installs/wsl.js +0 -572
- package/src/installs/wsl.md +0 -699
- package/src/installs/xcode-clt.js +0 -520
- package/src/installs/xcode-clt.md +0 -351
- package/src/installs/xcode.js +0 -560
- package/src/installs/xcode.md +0 -573
- package/src/installs/yarn.js +0 -824
- package/src/installs/yarn.md +0 -1074
- package/src/installs/yq.js +0 -654
- package/src/installs/yq.md +0 -944
- package/src/installs/yt-dlp.js +0 -701
- package/src/installs/yt-dlp.md +0 -946
- package/src/installs/yum-utils.js +0 -297
- package/src/installs/yum-utils.md +0 -648
- package/src/installs/zoom.js +0 -759
- package/src/installs/zoom.md +0 -884
- package/src/installs/zsh.js +0 -455
- package/src/installs/zsh.md +0 -1008
- package/src/scripts/README.md +0 -617
- package/src/scripts/STATUS.md +0 -208
- package/src/scripts/afk.js +0 -411
- package/src/scripts/backup-all.js +0 -746
- package/src/scripts/backup-source.js +0 -727
- package/src/scripts/brewd.js +0 -389
- package/src/scripts/brewi.js +0 -520
- package/src/scripts/brewr.js +0 -527
- package/src/scripts/brews.js +0 -477
- package/src/scripts/brewu.js +0 -504
- package/src/scripts/c.js +0 -201
- package/src/scripts/ccurl.js +0 -341
- package/src/scripts/certbot-crontab-init.js +0 -504
- package/src/scripts/certbot-init.js +0 -657
- package/src/scripts/ch.js +0 -355
- package/src/scripts/claude-danger.js +0 -268
- package/src/scripts/clean-dev.js +0 -435
- package/src/scripts/clear-dns-cache.js +0 -541
- package/src/scripts/clone.js +0 -435
- package/src/scripts/code-all.js +0 -437
- package/src/scripts/count-files.js +0 -211
- package/src/scripts/count-folders.js +0 -211
- package/src/scripts/count.js +0 -264
- package/src/scripts/d.js +0 -219
- package/src/scripts/datauri.js +0 -389
- package/src/scripts/delete-files.js +0 -380
- package/src/scripts/docker-clean.js +0 -426
- package/src/scripts/dp.js +0 -442
- package/src/scripts/e.js +0 -390
- package/src/scripts/empty-trash.js +0 -513
- package/src/scripts/evm.js +0 -444
- package/src/scripts/fetch-github-repos.js +0 -456
- package/src/scripts/get-channel.js +0 -345
- package/src/scripts/get-course.js +0 -399
- package/src/scripts/get-dependencies.js +0 -306
- package/src/scripts/get-folder.js +0 -799
- package/src/scripts/get-tunes.js +0 -426
- package/src/scripts/get-video.js +0 -367
- package/src/scripts/git-backup.js +0 -577
- package/src/scripts/git-clone.js +0 -493
- package/src/scripts/git-pup.js +0 -319
- package/src/scripts/git-push.js +0 -396
- package/src/scripts/h.js +0 -622
- package/src/scripts/hide-desktop-icons.js +0 -499
- package/src/scripts/hide-hidden-files.js +0 -538
- package/src/scripts/install-dependencies-from.js +0 -456
- package/src/scripts/ips.js +0 -663
- package/src/scripts/iso.js +0 -370
- package/src/scripts/killni.js +0 -577
- package/src/scripts/ll.js +0 -467
- package/src/scripts/local-ip.js +0 -325
- package/src/scripts/m.js +0 -524
- package/src/scripts/map.js +0 -309
- package/src/scripts/mkd.js +0 -351
- package/src/scripts/ncu-update-all.js +0 -457
- package/src/scripts/nginx-init.js +0 -718
- package/src/scripts/npmi.js +0 -382
- package/src/scripts/o.js +0 -511
- package/src/scripts/org-by-date.js +0 -338
- package/src/scripts/p.js +0 -224
- package/src/scripts/packages.js +0 -330
- package/src/scripts/path.js +0 -225
- package/src/scripts/ports.js +0 -597
- package/src/scripts/q.js +0 -305
- package/src/scripts/refresh-files.js +0 -394
- package/src/scripts/remove-smaller-files.js +0 -516
- package/src/scripts/rename-files-with-date.js +0 -533
- package/src/scripts/resize-image.js +0 -539
- package/src/scripts/rm-safe.js +0 -669
- package/src/scripts/s.js +0 -540
- package/src/scripts/set-git-public.js +0 -365
- package/src/scripts/show-desktop-icons.js +0 -475
- package/src/scripts/show-hidden-files.js +0 -472
- package/src/scripts/tpa.js +0 -280
- package/src/scripts/tpo.js +0 -280
- package/src/scripts/u.js +0 -505
- package/src/scripts/vpush.js +0 -437
- package/src/scripts/y.js +0 -283
- package/src/utils/README.md +0 -95
- package/src/utils/common/apps.js +0 -143
- package/src/utils/common/display.js +0 -157
- package/src/utils/common/network.js +0 -185
- package/src/utils/common/os.js +0 -294
- package/src/utils/common/package-manager.js +0 -301
- package/src/utils/common/privileges.js +0 -138
- package/src/utils/common/shell.js +0 -261
- package/src/utils/macos/apps.js +0 -228
- package/src/utils/macos/brew.js +0 -315
- package/src/utils/ubuntu/apt.js +0 -307
- package/src/utils/ubuntu/desktop.js +0 -292
- package/src/utils/ubuntu/snap.js +0 -344
- package/src/utils/ubuntu/systemd.js +0 -286
- package/src/utils/windows/choco.js +0 -465
- package/src/utils/windows/env.js +0 -246
- package/src/utils/windows/registry.js +0 -269
- package/src/utils/windows/shell.js +0 -240
- package/src/utils/windows/winget.js +0 -489
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const shell = require('../../lib/shell');
|
|
4
|
+
const { checkQmd } = require('./qmd');
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
description: 'Retrieve a document by file path or QMD document ID',
|
|
8
|
+
arguments: [
|
|
9
|
+
{ name: 'target', description: 'File path or document ID (e.g., #abc123)', required: true }
|
|
10
|
+
],
|
|
11
|
+
flags: [
|
|
12
|
+
{ name: 'full', type: 'boolean', description: 'Return the entire document instead of a snippet' },
|
|
13
|
+
{ name: 'line', type: 'number', description: 'Start at a specific line number' },
|
|
14
|
+
{ name: 'max-lines', type: 'number', description: 'Maximum number of lines to return' }
|
|
15
|
+
]
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Retrieves a document by file path or QMD document ID.
|
|
20
|
+
* Passes the target through to QMD as-is (QMD handles both
|
|
21
|
+
* file paths and #id-style document IDs).
|
|
22
|
+
*
|
|
23
|
+
* @param {object} args - Parsed CLI arguments { positional, flags }.
|
|
24
|
+
* @param {object} context - CLI context { output, errors }.
|
|
25
|
+
*/
|
|
26
|
+
async function run(args, context) {
|
|
27
|
+
// Check for QMD availability first
|
|
28
|
+
const qmd = checkQmd();
|
|
29
|
+
if (!qmd.available) {
|
|
30
|
+
context.errors.throwError(1, qmd.message, 'search');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const target = args.positional[0];
|
|
35
|
+
|
|
36
|
+
if (!target) {
|
|
37
|
+
context.errors.throwError(400, 'Missing required argument: <target>. Example: dev search get path/to/document.md', 'search');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Build the QMD command
|
|
42
|
+
let cmd = `qmd get "${target}"`;
|
|
43
|
+
|
|
44
|
+
if (args.flags.full) {
|
|
45
|
+
cmd += ' --full';
|
|
46
|
+
}
|
|
47
|
+
if (args.flags.line) {
|
|
48
|
+
cmd += ` --line ${args.flags.line}`;
|
|
49
|
+
}
|
|
50
|
+
if (args.flags['max-lines']) {
|
|
51
|
+
cmd += ` --max-lines ${args.flags['max-lines']}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Execute and capture output
|
|
55
|
+
const result = await shell.exec(cmd);
|
|
56
|
+
|
|
57
|
+
if (result.exitCode !== 0) {
|
|
58
|
+
context.errors.throwError(1, result.stderr || `Document not found: ${target}`, 'search');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// For get, the output is document content, not search results
|
|
63
|
+
const output = {
|
|
64
|
+
target: target,
|
|
65
|
+
content: result.stdout
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
context.output.out(output);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = { meta, run };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const shell = require('../../lib/shell');
|
|
4
|
+
const { checkQmd } = require('./qmd');
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
description: 'Rebuild or update the search index and generate embeddings',
|
|
8
|
+
arguments: [],
|
|
9
|
+
flags: [
|
|
10
|
+
{ name: 'force', type: 'boolean', description: 'Re-index everything from scratch (ignores incremental updates)' }
|
|
11
|
+
]
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Rebuilds or updates the QMD search index.
|
|
16
|
+
* Triggers re-indexing of all collections and embedding generation.
|
|
17
|
+
* Use --force to ignore incremental updates and rebuild from scratch.
|
|
18
|
+
*
|
|
19
|
+
* @param {object} args - Parsed CLI arguments { positional, flags }.
|
|
20
|
+
* @param {object} context - CLI context { output, errors }.
|
|
21
|
+
*/
|
|
22
|
+
async function run(args, context) {
|
|
23
|
+
// Check for QMD availability first
|
|
24
|
+
const qmd = checkQmd();
|
|
25
|
+
if (!qmd.available) {
|
|
26
|
+
context.errors.throwError(1, qmd.message, 'search');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Build the command
|
|
31
|
+
let cmd = 'qmd index';
|
|
32
|
+
if (args.flags.force) {
|
|
33
|
+
cmd += ' --force';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Print progress messages before starting
|
|
37
|
+
context.output.info('Updating search index...');
|
|
38
|
+
if (args.flags.force) {
|
|
39
|
+
context.output.info('Force flag set -- re-indexing all documents from scratch.');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Execute the index command
|
|
43
|
+
const result = await shell.exec(cmd);
|
|
44
|
+
|
|
45
|
+
if (result.exitCode !== 0) {
|
|
46
|
+
context.errors.throwError(1, result.stderr || 'Index update failed.', 'search');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Pass through QMD's output (informational, not structured data)
|
|
51
|
+
context.output.info(result.stdout || 'Index updated successfully.');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = { meta, run };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search service registration.
|
|
3
|
+
* Markdown search via QMD (requires separate install).
|
|
4
|
+
*
|
|
5
|
+
* All commands in this service check for QMD availability first.
|
|
6
|
+
* If QMD is not installed, they return an error with installation
|
|
7
|
+
* instructions: bun install -g @tobilu/qmd
|
|
8
|
+
*/
|
|
9
|
+
module.exports = {
|
|
10
|
+
name: 'search',
|
|
11
|
+
description: 'Markdown search via QMD',
|
|
12
|
+
commands: {
|
|
13
|
+
query: () => require('./query'),
|
|
14
|
+
keyword: () => require('./keyword'),
|
|
15
|
+
semantic: () => require('./semantic'),
|
|
16
|
+
get: () => require('./get'),
|
|
17
|
+
collections: () => require('./collections'),
|
|
18
|
+
index: () => require('./index-cmd'),
|
|
19
|
+
status: () => require('./status'),
|
|
20
|
+
}
|
|
21
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { checkQmd, runQmdSearch } = require('./qmd');
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
description: 'Fast BM25 full-text keyword search',
|
|
7
|
+
arguments: [
|
|
8
|
+
{ name: 'query', description: 'Search query text', required: true }
|
|
9
|
+
],
|
|
10
|
+
flags: [
|
|
11
|
+
{ name: 'collection', type: 'string', description: 'Restrict search to a specific collection' },
|
|
12
|
+
{ name: 'limit', type: 'number', description: 'Maximum number of results to return (default: 10)' }
|
|
13
|
+
]
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Runs a BM25 keyword search via QMD.
|
|
18
|
+
* Fast exact-term matching without vector similarity or LLM re-ranking.
|
|
19
|
+
*
|
|
20
|
+
* @param {object} args - Parsed CLI arguments { positional, flags }.
|
|
21
|
+
* @param {object} context - CLI context { output, errors }.
|
|
22
|
+
*/
|
|
23
|
+
async function run(args, context) {
|
|
24
|
+
// Check for QMD availability first
|
|
25
|
+
const qmd = checkQmd();
|
|
26
|
+
if (!qmd.available) {
|
|
27
|
+
context.errors.throwError(1, qmd.message, 'search');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const query = args.positional[0];
|
|
32
|
+
|
|
33
|
+
if (!query) {
|
|
34
|
+
context.errors.throwError(400, 'Missing required argument: <query>. Example: dev search keyword "SSH key"', 'search');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Build the QMD command
|
|
39
|
+
let cmd = `qmd keyword "${query}"`;
|
|
40
|
+
|
|
41
|
+
if (args.flags.collection) {
|
|
42
|
+
cmd += ` --collection "${args.flags.collection}"`;
|
|
43
|
+
}
|
|
44
|
+
if (args.flags.limit) {
|
|
45
|
+
cmd += ` --limit ${args.flags.limit}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Execute and parse results
|
|
49
|
+
const results = await runQmdSearch(cmd, context);
|
|
50
|
+
if (results === null) return; // error already reported
|
|
51
|
+
|
|
52
|
+
if (results.length === 0) {
|
|
53
|
+
context.output.info('No results found.');
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
context.output.out(results);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = { meta, run };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const shell = require('../../lib/shell');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Checks if QMD is installed and available on the system PATH.
|
|
7
|
+
* Every search command calls this before doing anything else.
|
|
8
|
+
*
|
|
9
|
+
* @returns {object} { available: true } if found, or { available: false, message: '...' } if not.
|
|
10
|
+
*/
|
|
11
|
+
function checkQmd() {
|
|
12
|
+
const isInstalled = shell.commandExists('qmd');
|
|
13
|
+
|
|
14
|
+
if (!isInstalled) {
|
|
15
|
+
return {
|
|
16
|
+
available: false,
|
|
17
|
+
message: 'QMD is not installed. Install it with: bun install -g @tobilu/qmd'
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return { available: true };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Parses search results from QMD output.
|
|
26
|
+
* Tries JSON first, then falls back to line-delimited text.
|
|
27
|
+
* Returns an empty array for empty or null output.
|
|
28
|
+
*
|
|
29
|
+
* Output format may vary by QMD version.
|
|
30
|
+
*
|
|
31
|
+
* @param {string} output - The raw stdout from a QMD search command.
|
|
32
|
+
* @returns {Array<object>} Parsed search results.
|
|
33
|
+
*/
|
|
34
|
+
function parseSearchResults(output) {
|
|
35
|
+
if (!output || !output.trim()) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Try JSON first
|
|
40
|
+
try {
|
|
41
|
+
const parsed = JSON.parse(output);
|
|
42
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
43
|
+
} catch (err) {
|
|
44
|
+
// Fall back to line-delimited text
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Parse as line-delimited results
|
|
48
|
+
return output.trim().split('\n').filter(Boolean).map(line => ({ raw: line }));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Runs a QMD search command and parses the results.
|
|
53
|
+
* Returns null if the command fails (error is reported via context.errors).
|
|
54
|
+
*
|
|
55
|
+
* @param {string} cmd - The full QMD command to run.
|
|
56
|
+
* @param {object} context - The CLI context (needs context.errors).
|
|
57
|
+
* @returns {Promise<Array<object>|null>} Parsed results, or null on failure.
|
|
58
|
+
*/
|
|
59
|
+
async function runQmdSearch(cmd, context) {
|
|
60
|
+
const result = await shell.exec(cmd);
|
|
61
|
+
|
|
62
|
+
if (result.exitCode !== 0) {
|
|
63
|
+
context.errors.throwError(1, result.stderr || `QMD command failed: ${cmd}`, 'search');
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return parseSearchResults(result.stdout);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = { checkQmd, parseSearchResults, runQmdSearch };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { checkQmd, runQmdSearch } = require('./qmd');
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
description: 'Hybrid search combining BM25 keyword matching, vector similarity, and LLM re-ranking',
|
|
7
|
+
arguments: [
|
|
8
|
+
{ name: 'query', description: 'Search query text', required: true }
|
|
9
|
+
],
|
|
10
|
+
flags: [
|
|
11
|
+
{ name: 'collection', type: 'string', description: 'Restrict search to a specific collection' },
|
|
12
|
+
{ name: 'limit', type: 'number', description: 'Maximum number of results to return (default: 10)' },
|
|
13
|
+
{ name: 'min-score', type: 'number', description: 'Minimum relevance score between 0.0 and 1.0' }
|
|
14
|
+
]
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Runs a hybrid search (BM25 + vector + LLM re-ranking) via QMD.
|
|
19
|
+
* Provides the highest quality results at the cost of speed.
|
|
20
|
+
*
|
|
21
|
+
* @param {object} args - Parsed CLI arguments { positional, flags }.
|
|
22
|
+
* @param {object} context - CLI context { output, errors }.
|
|
23
|
+
*/
|
|
24
|
+
async function run(args, context) {
|
|
25
|
+
// Check for QMD availability first
|
|
26
|
+
const qmd = checkQmd();
|
|
27
|
+
if (!qmd.available) {
|
|
28
|
+
context.errors.throwError(1, qmd.message, 'search');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const query = args.positional[0];
|
|
33
|
+
|
|
34
|
+
if (!query) {
|
|
35
|
+
context.errors.throwError(400, 'Missing required argument: <query>. Example: dev search query "how to configure SSH"', 'search');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Build the QMD command
|
|
40
|
+
let cmd = `qmd query "${query}"`;
|
|
41
|
+
|
|
42
|
+
if (args.flags.collection) {
|
|
43
|
+
cmd += ` --collection "${args.flags.collection}"`;
|
|
44
|
+
}
|
|
45
|
+
if (args.flags.limit) {
|
|
46
|
+
cmd += ` --limit ${args.flags.limit}`;
|
|
47
|
+
}
|
|
48
|
+
if (args.flags['min-score']) {
|
|
49
|
+
cmd += ` --min-score ${args.flags['min-score']}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Execute and parse results
|
|
53
|
+
const results = await runQmdSearch(cmd, context);
|
|
54
|
+
if (results === null) return; // error already reported
|
|
55
|
+
|
|
56
|
+
if (results.length === 0) {
|
|
57
|
+
context.output.info('No results found.');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
context.output.out(results);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = { meta, run };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { checkQmd, runQmdSearch } = require('./qmd');
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
description: 'Vector cosine similarity search for conceptually related content',
|
|
7
|
+
arguments: [
|
|
8
|
+
{ name: 'query', description: 'Search query text', required: true }
|
|
9
|
+
],
|
|
10
|
+
flags: [
|
|
11
|
+
{ name: 'collection', type: 'string', description: 'Restrict search to a specific collection' },
|
|
12
|
+
{ name: 'limit', type: 'number', description: 'Maximum number of results to return (default: 10)' }
|
|
13
|
+
]
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Runs a vector cosine similarity search via QMD.
|
|
18
|
+
* Finds conceptually similar content even when the exact words don't match.
|
|
19
|
+
* Requires embeddings to be generated first (via dev search index).
|
|
20
|
+
*
|
|
21
|
+
* @param {object} args - Parsed CLI arguments { positional, flags }.
|
|
22
|
+
* @param {object} context - CLI context { output, errors }.
|
|
23
|
+
*/
|
|
24
|
+
async function run(args, context) {
|
|
25
|
+
// Check for QMD availability first
|
|
26
|
+
const qmd = checkQmd();
|
|
27
|
+
if (!qmd.available) {
|
|
28
|
+
context.errors.throwError(1, qmd.message, 'search');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const query = args.positional[0];
|
|
33
|
+
|
|
34
|
+
if (!query) {
|
|
35
|
+
context.errors.throwError(400, 'Missing required argument: <query>. Example: dev search semantic "remote server access"', 'search');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Build the QMD command
|
|
40
|
+
let cmd = `qmd semantic "${query}"`;
|
|
41
|
+
|
|
42
|
+
if (args.flags.collection) {
|
|
43
|
+
cmd += ` --collection "${args.flags.collection}"`;
|
|
44
|
+
}
|
|
45
|
+
if (args.flags.limit) {
|
|
46
|
+
cmd += ` --limit ${args.flags.limit}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Execute and parse results
|
|
50
|
+
const results = await runQmdSearch(cmd, context);
|
|
51
|
+
if (results === null) return; // error already reported
|
|
52
|
+
|
|
53
|
+
if (results.length === 0) {
|
|
54
|
+
// Check if this might be an embeddings issue
|
|
55
|
+
context.output.info('No results found. If embeddings have not been generated, run "dev search index" first.');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
context.output.out(results);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = { meta, run };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const shell = require('../../lib/shell');
|
|
4
|
+
const { checkQmd, parseSearchResults } = require('./qmd');
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
description: 'Show search index health, collection count, and document count',
|
|
8
|
+
arguments: [],
|
|
9
|
+
flags: []
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Shows the health and status of the QMD search index.
|
|
14
|
+
* Displays collection count, document count, last update time, and health.
|
|
15
|
+
*
|
|
16
|
+
* @param {object} args - Parsed CLI arguments { positional, flags }.
|
|
17
|
+
* @param {object} context - CLI context { output, errors }.
|
|
18
|
+
*/
|
|
19
|
+
async function run(args, context) {
|
|
20
|
+
// Check for QMD availability first
|
|
21
|
+
const qmd = checkQmd();
|
|
22
|
+
if (!qmd.available) {
|
|
23
|
+
context.errors.throwError(1, qmd.message, 'search');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Run qmd status and capture the output
|
|
28
|
+
const result = await shell.exec('qmd status');
|
|
29
|
+
|
|
30
|
+
if (result.exitCode !== 0) {
|
|
31
|
+
context.errors.throwError(1, result.stderr || 'Failed to get search index status.', 'search');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Try to parse the output as JSON for structured data
|
|
36
|
+
const output = result.stdout;
|
|
37
|
+
try {
|
|
38
|
+
const parsed = JSON.parse(output);
|
|
39
|
+
context.output.out(parsed);
|
|
40
|
+
} catch (err) {
|
|
41
|
+
// QMD returned non-JSON output, pass it through as-is
|
|
42
|
+
context.output.info(output || 'No status information available.');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = { meta, run };
|