├── .gitbook.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── README.md ├── commands ├── call-zapier-with-input │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── convert-hex-to-tailwind │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── convert-opacity-to-hex │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── github-stars │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── hacker-news-front-page │ ├── README.md │ ├── command.toml │ ├── icon.svg │ └── screenshot.json ├── parse-user-agent │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── rss-feed │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── search-chakra-ui-docs │ ├── README.md │ ├── command.toml │ ├── icon.svg │ └── screenshot.json ├── search-clerk-docs │ ├── README.md │ ├── command.toml │ ├── icon.svg │ └── screenshot.json ├── search-emojis │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── search-honeycomb-boards │ ├── README.md │ ├── command.toml │ ├── icon.svg │ └── screenshot.json ├── search-iconfinder │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── search-nextjs-docs │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── search-npm │ ├── README.md │ ├── command.toml │ ├── icon.svg │ └── screenshot.json ├── search-slapdash-platform-docs │ ├── README.md │ ├── command.toml │ ├── icon.svg │ └── screenshot.json ├── search-supabase-docs │ ├── README.md │ ├── command.toml │ ├── icon.svg │ └── screenshot.json ├── search-tailwind-css-docs │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── search-unsplash │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── show-current-unix-timestamp │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json └── vercel-projects │ ├── README.md │ ├── command.toml │ ├── icon.monochrome.svg │ └── screenshot.json ├── docs ├── .gitbook │ └── assets │ │ ├── cleanshot-2021-08-20-at-16.22.14.png │ │ ├── cleanshot-2021-08-20-at-16.27.46.png │ │ ├── command-fux.gif │ │ ├── copy-special-character.gif │ │ ├── emoji-paster.gif │ │ ├── image (1).png │ │ ├── image (2).png │ │ ├── image (3).png │ │ ├── image.png │ │ ├── screen-shot-2021-06-11-at-8.26.45-pm.png │ │ ├── screen-shot-2021-06-11-at-8.27.53-pm.png │ │ ├── screen-shot-2021-06-11-at-8.28.24-pm.png │ │ ├── screen-shot-2021-06-11-at-8.28.52-pm.png │ │ ├── screen-shot-2021-06-11-at-8.30.10-pm.png │ │ ├── screen-shot-2021-06-11-at-8.31.38-pm.png │ │ ├── screen-shot-2021-06-15-at-5.37.17-pm.png │ │ ├── screen-shot-2021-06-15-at-5.38.22-pm.png │ │ ├── screen-shot-2021-06-15-at-5.40.26-pm.png │ │ ├── screen-shot-2021-06-18-at-1.38.33-am.png │ │ ├── screen-shot-2021-06-18-at-3.10.48-pm.png │ │ ├── screen-shot-2021-06-20-at-2.29.56-pm.png │ │ ├── screen-shot-2021-06-20-at-2.31.40-pm.png │ │ ├── screen-shot-2021-06-21-at-12.16.21-am.png │ │ ├── screen_shot_2021-05-19_at_11.25.08_pm (1).png │ │ ├── screen_shot_2021-05-19_at_11.25.08_pm.png │ │ ├── screen_shot_2021-05-19_at_11.26.46_pm.png │ │ ├── screen_shot_2021-05-23_at_3.35.09_pm.png │ │ ├── screen_shot_2021-05-25_at_10.19.37_pm.png │ │ ├── send-slack-message.gif │ │ ├── test-1-.png │ │ ├── test.png │ │ ├── toggle-dark-mode (1) (2) (2) (2) (1).gif │ │ ├── toggle-dark-mode (1) (2) (2) (2) (2) (1).gif │ │ ├── toggle-dark-mode (1) (2) (2) (2) (2) (2).gif │ │ ├── toggle-dark-mode (1) (2) (2) (2) (2).gif │ │ └── toggle-dark-mode (1) (2) (2) (2).gif ├── README.md ├── command-bar-101 │ ├── cloud-commands.md │ ├── commands.md │ ├── core-terminology.md │ ├── hooks.md │ ├── how-it-works.md │ ├── local-commands.md │ ├── publish-command.md │ └── setup-your-first-command.md ├── command-tutorials │ ├── copy-special-character.md │ ├── emoji-paster.md │ ├── send-slack-message.md │ └── toggle-dark-mode.md ├── reference │ ├── command-response-action.md │ ├── command-response-config.md │ ├── command-response-icon.md │ ├── command-response-tokens.md │ ├── command-response-view-form.md │ ├── command-response-view-list.md │ ├── command-response-view-masonry.md │ ├── command-response-view.md │ ├── command-response.md │ ├── custom-config.js │ ├── form-view.js │ ├── list-view.js │ ├── masonry-view.js │ └── open-url.js └── root.md ├── packages └── command-response-types │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── index.d.ts │ └── package.json ├── templates ├── bash │ └── ahoy-world.sh ├── custom-shebang-not-bash.sh ├── javascript │ └── ahoy-world.js ├── perl │ └── ahoy-world.pl ├── php │ └── ahoy-world.php ├── python │ └── ahoy-world.py ├── ruby │ └── ahoy-world.rb └── typescript │ ├── global │ ├── README.md │ └── ahoy-world.ts │ └── package │ ├── README.md │ ├── ahoy-world.ts │ └── package.json └── tutorials ├── copy-special-character └── copy-special-character.js ├── emoji-paster └── emoji-paster.js └── toggle-dark-mode └── toggle-dark-mode.applescript /.gitbook.yaml: -------------------------------------------------------------------------------- 1 | root: ./docs/ 2 | 3 | structure: 4 | readme: root.md 5 | summary: README.md 6 | 7 | redirects: 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | package-lock.json 4 | yarn.lock 5 | .history -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to make participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Giving and gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies within all project spaces, and it also applies when 49 | an individual is representing the project or its community in public spaces. 50 | Examples of representing a project or community include using an official 51 | project e-mail address, posting via an official social media account, or acting 52 | as an appointed representative at an online or offline event. Representation of 53 | a project may be further defined and clarified by project maintainers. 54 | 55 | This Code of Conduct also applies outside the project spaces when there is a 56 | reasonable belief that an individual's behavior may have a negative impact on 57 | the project or its community. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported by contacting the project team at . All 63 | complaints will be reviewed and investigated and will result in a response that 64 | is deemed necessary and appropriate to the circumstances. The project team is 65 | obligated to maintain confidentiality with regard to the reporter of an incident. 66 | Further details of specific enforcement policies may be posted separately. 67 | 68 | Project maintainers who do not follow or enforce the Code of Conduct in good 69 | faith may face temporary or permanent repercussions as determined by other 70 | members of the project's leadership. 71 | 72 | ## Attribution 73 | 74 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 75 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 76 | 77 | [homepage]: https://www.contributor-covenant.org 78 | 79 | For answers to common questions about this code of conduct, see 80 | https://www.contributor-covenant.org/faq -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for your interest in contributing to Slapdash Platform. 4 | 5 | Our repo adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). 6 | By participating, you are expected to uphold this code. Please report unacceptable 7 | behavior to . 8 | 9 | Here you'll find a set of guidelines for contributing to Slapdash Platform. 10 | These are just guidelines, not rules, use your best judgment and feel free to 11 | propose changes to this document in a pull request. 12 | 13 | ## Pull Requests 14 | 15 | Please make sure that your pull request makes it easy for the reviewer to understand what the change is about. Keep your change focused. 16 | 17 | ### Add New Command 18 | 19 | To add a new command please follow the tutorial at https://developers.slapdash.com/command-bar-101/publish-command. 20 | 21 | ## Issues 22 | 23 | Feel free to file new issues for bug reports and suggestions. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Slapdash Platform 2 | 3 | This repository contains documentation, tools and examples for extending Slapdash. 4 | 5 | ### Documentation 6 | 7 | Documentation is published to [platform.slapdash.com](https://platform.slapdash.com) via GitBook and is backed by the [docs directory](docs/) in this repository. 8 | 9 | ### Publish Command 10 | 11 | Commands built by the community can be found in the [commands directory](commands/). All these commands are [featured on Slapdash](https://slapdash.com/developers) where everyone can discover them and add to their Slapdash accounts. 12 | 13 | If you want to publish your command, [check out the instructions](https://developers.slapdash.com/command-bar-101/publish-command). 14 | 15 | ### Language-specific Templates 16 | 17 | We maintain simple examples of how you can write commands in the language of your choice in the [templates directory](templates/). 18 | 19 | ### Command Response TypeScript Types 20 | 21 | If you are writing a command in TypeScript, we maintain a package of [types for the Command Response](packages/command-response-types) specification. 22 | 23 | 24 | -------------------------------------------------------------------------------- /commands/call-zapier-with-input/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/call-zapier-with-input -------------------------------------------------------------------------------- /commands/call-zapier-with-input/command.toml: -------------------------------------------------------------------------------- 1 | name = "Call Zapier with Input" 2 | description = "Configurable command to call a Zap webhook and pass data" 3 | endpointURL = "https://call-zapier-with-input.ivankanevski.repl.co" 4 | sourceCodeURL = "https://replit.com/@IvanKanevski/call-zapier-with-input" 5 | 6 | language = "python" 7 | categories = ["Automation"] 8 | 9 | author.name = "Ivan Kanevski" 10 | author.profileURL = "https://kanevski.org/" 11 | 12 | readme = """ 13 | The first time you run this command, it will ask you for a webhook URL 14 | for a [Zapier](https://zapier.com/) zap. 15 | 16 | On subsequent runs, the command will prompt you for input. You'll be able 17 | to enter whatever text and after hitting Enter, the Zapier webhook URL 18 | will be hit with the input you provided. 19 | """ 20 | -------------------------------------------------------------------------------- /commands/call-zapier-with-input/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /commands/call-zapier-with-input/screenshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "keywords": "email@example.com", 3 | "response": { 4 | "inputPlaceholder": "", 5 | "view": { 6 | "options": [ 7 | { 8 | "action": { 9 | "name": "submit", 10 | "type": "add-param", 11 | "value": "email@example.com" 12 | }, 13 | "title": "Run Zap with input: email@example.com" 14 | } 15 | ], 16 | "ranking": false, 17 | "type": "list" 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /commands/convert-hex-to-tailwind/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/convert-hex-to-tailwind 2 | -------------------------------------------------------------------------------- /commands/convert-hex-to-tailwind/command.toml: -------------------------------------------------------------------------------- 1 | name = "Convert Hex Color to Tailwind Preset" 2 | description = "Command to convert hex color to Tailwind preset" 3 | endpointURL = "https://tailwind-color-finder.vercel.app/api/slapdash/hex-to-tailwind-command" 4 | sourceCodeURL = "https://github.com/TedisAgolli/tailwind-color-finder/blob/master/pages/api/slapdash/hex-to-tailwind-command.js" 5 | 6 | language = "javascript" 7 | categories = ["Developer Tools", "Utilities"] 8 | 9 | author.name = "Tedis Agolli" 10 | author.profileURL = "https://twitter.com/TedisAgolli" 11 | 12 | readme = """ 13 | Pass a valid hex color, e.g. `#fff` and the command will return the closest 14 | Tailwind preset; in this case `true-gray-50`. 15 | 16 | Below the color you will see the Delta-E, which is the difference between the two colors. 17 | There will also be a plain language explanation of the Delta-E, such as "Perceptible through close observation". 18 | Here is a source explaining [Delta-E](http://zschuessler.github.io/DeltaE/learn/). 19 | """ 20 | -------------------------------------------------------------------------------- /commands/convert-hex-to-tailwind/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /commands/convert-hex-to-tailwind/screenshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "keywords": "fff", 3 | "response": { 4 | "view": { 5 | "ranking": false, 6 | "type": "list", 7 | "options": [ 8 | { 9 | "title": "Copy Tailwind: trueGray-50 ", 10 | "action": { 11 | "type": "copy", 12 | "value": "trueGray-50" 13 | }, 14 | "subtitle": [ 15 | "DeltaE: 1.73", 16 | "Perceptible through close observation" 17 | ] 18 | } 19 | ] 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /commands/convert-opacity-to-hex/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/convert-opacity-to-hex -------------------------------------------------------------------------------- /commands/convert-opacity-to-hex/command.toml: -------------------------------------------------------------------------------- 1 | name = "Convert Opacity to Hex" 2 | description = "Converts CSS opacity in percent to its hex value." 3 | endpointURL = "https://kanevski.org/commands/opacity-to-hex" 4 | 5 | language = "typescript" 6 | categories = ["Developer Tools", "Calculator"] 7 | 8 | author.name = "Ivan Kanevski" 9 | author.profileURL = "https://kanevski.org/" 10 | 11 | readme = """ 12 | A simple calculator that converts a numeric percentage value representing opacity 13 | to its hex representation. 14 | 15 | Helpful if you want to represent transparency with hex. For example, setting the color 16 | black (#000000) with 50% opacity, you would prepend 80, which is the hex value for 50 (#80000000). 17 | """ -------------------------------------------------------------------------------- /commands/convert-opacity-to-hex/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /commands/convert-opacity-to-hex/screenshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "keywords": "48", 3 | "response": { 4 | "inputPlaceholder": "", 5 | "view": { 6 | "ranking": false, 7 | "type": "list", 8 | "options": [ 9 | { 10 | "title": "Copy Hex: 7A ", 11 | "action": { 12 | "type": "copy", 13 | "value": "7A" 14 | } 15 | } 16 | ] 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /commands/github-stars/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/github-stars -------------------------------------------------------------------------------- /commands/github-stars/command.toml: -------------------------------------------------------------------------------- 1 | name = "Github Stars" 2 | description = "Search across Github Repositories that you have starred before" 3 | endpointURL = "https://www.taraszubyk.com/api/slapdash/github-stars" 4 | sourceCodeURL = "https://github.com/zuta/slapdash-commands/blob/master/api/slapdash/github-stars.ts" 5 | 6 | language = "typescript" 7 | categories = ["Developer Tools"] 8 | 9 | author.name = "Taras Zubyk" 10 | author.profileURL = "https://twitter.com/_zuta_/" 11 | 12 | readme = """ 13 | The command shows the last repositories you have starred on [Github](https://github.com) and allows you to quickly search across them. 14 | 15 | To use the command, you'll need to generate a [Github Personal Access Token](https://github.com/settings/tokens/new). When you run the command for the first time it will ask you to provide this access token. 16 | 17 | Press `ENTER` to open the repository on Github or press `TAB` to see more options (e.g. open the repo's homepage). 18 | """ -------------------------------------------------------------------------------- /commands/github-stars/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commands/hacker-news-front-page/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/hacker-news-front-page -------------------------------------------------------------------------------- /commands/hacker-news-front-page/command.toml: -------------------------------------------------------------------------------- 1 | name = "Hacker News Front Page" 2 | description = "Scan through the Hacker News front page and jump to posts or comments." 3 | endpointURL = "https://www.taraszubyk.com/api/slapdash/hn-front-page" 4 | sourceCodeURL = "https://github.com/zuta/slapdash-commands/blob/master/api/slapdash/hn-front-page.ts" 5 | 6 | language = "typescript" 7 | categories = ["News"] 8 | 9 | author.name = "Taras Zubyk" 10 | author.profileURL = "https://twitter.com/_zuta_/" 11 | 12 | readme = """ 13 | This command uses the [RSS Feed](https://hnrss.org/frontpage) of the [Hacker News](https://news.ycombinator.com/) front page to let you quickly scan 14 | through the latest posts. 15 | 16 | Each option in the list displays the post's title, information about the author and some insights e.g. the number of comments that were made on Hacker News. 17 | You can choose to jump directly to the post or the comments section on Hacker News. 18 | """ -------------------------------------------------------------------------------- /commands/hacker-news-front-page/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /commands/parse-user-agent/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/parse-user-agent -------------------------------------------------------------------------------- /commands/parse-user-agent/command.toml: -------------------------------------------------------------------------------- 1 | name = "Parse User-Agent" 2 | description = "Parse a User-Agent string by pasting it into the Command Bar." 3 | endpointURL = "https://www.taraszubyk.com/api/slapdash/parse-user-agent" 4 | sourceCodeURL = "https://github.com/zuta/slapdash-commands/blob/master/api/slapdash/parse-user-agent.ts" 5 | language = "typescript" 6 | categories = ["Developer Tools"] 7 | 8 | author.name = "Taras Zubyk" 9 | author.profileURL = "https://twitter.com/_zuta_" 10 | 11 | readme = """ 12 | This command parses a [User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) string entered into the Command Bar input and displays data in a structured way separating the browser, OS and device type. 13 | 14 | For the best experience, you can assign an alias or a keyboard shortcut to get to the command faster. 15 | """ -------------------------------------------------------------------------------- /commands/parse-user-agent/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /commands/parse-user-agent/screenshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "keywords": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1", 3 | "response": { 4 | "inputPlaceholder": "Paste a User-Agent string", 5 | "view": "OS: iOS 10.3.1\n\nBrowser: Mobile Safari 10.0\n\nDevice: Apple iPhone mobile\n\n" 6 | } 7 | } -------------------------------------------------------------------------------- /commands/rss-feed/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/rss-feed -------------------------------------------------------------------------------- /commands/rss-feed/command.toml: -------------------------------------------------------------------------------- 1 | name = "RSS Feed" 2 | description = "Quickly search and explore any RSS Feed" 3 | endpointURL = "https://RSS-Feed.taraszubyk.repl.co" 4 | sourceCodeURL = "https://replit.com/@taraszubyk/RSS-Feed" 5 | 6 | language = "typescript" 7 | categories = ["News", "Magazines & Newspapers"] 8 | 9 | author.name = "Taras Zubyk" 10 | author.profileURL = "https://twitter.com/_zuta_/" 11 | 12 | readme = """ 13 | The command lets you convert any RSS Feed into a searchable list in the Command Bar. Use it to quickly scan through the latest posts of your favourite publisher. 14 | 15 | The first time you run the command, you'll be asked to provide a URL for the RSS Feed. 16 | There are many RSS Feeds available but here are some popular ones that you might want to try: 17 | 18 | - [New York Times Home Page](https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml) – latest news from The New Your Times home page. 19 | - [Reddit Front Page](https://www.reddit.com/.rss) – latest posts from the front page on Reddit. In most cases, you can create an RSS feed by adding ".rss" to the end of an existing Reddit URL, e.g. http://www.reddit.com/r/news/.rss. 20 | - [Hacker News Front Page](https://hnrss.org/frontpage) – top 30 posts that have appeared on the front page of Hacker News. 21 | - [Hacker News Jobs](https://hnrss.org/jobs) – new job opportunities from YC funded startups. 22 | - [Product Hunt](https://www.producthunt.com/feed) – latest product launches on Product Hunt. Pro tip: add a `category` parameter to the Feed URL to access the feed for a specific category. For example, for the Productivity category, you can use https://www.producthunt.com/feed?category=productivity. 23 | 24 | Given the nature of this command, you can create multiple Slapdash Commands by using different RSS Feed URLs. Try changing the command's name and icon to give it an even better look. 25 | """ -------------------------------------------------------------------------------- /commands/rss-feed/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commands/search-chakra-ui-docs/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-chakra-ui-docs -------------------------------------------------------------------------------- /commands/search-chakra-ui-docs/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search Chakra UI Docs" 2 | description = "Search through Chakra UI documentation" 3 | endpointURL = "https://slapcommands.vercel.app/api/docsearch/chakra-ui" 4 | sourceCodeURL = "https://github.com/AnishDe12020/slapcommands/blob/main/src/shared/docsearch/chakra-ui-docs.js" 5 | language = "javascript" 6 | categories = ["Developer Tools", "Productivity", "Documentation"] 7 | 8 | author.name = "Anish De" 9 | author.profileURL = "https://github.com/AnishDe12020" 10 | 11 | readme = """ 12 | This command lets you search through the [Chakra UI documentation](https://chakra-ui.com/guides/first-steps). Also, you can copy the URL to the individual pages or paste it directly to your current application. 13 | 14 | The command is also [available](https://github.com/AnishDe12020/slapcommands) as a Local Command. 15 | """ 16 | -------------------------------------------------------------------------------- /commands/search-chakra-ui-docs/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commands/search-clerk-docs/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-clerk-docs -------------------------------------------------------------------------------- /commands/search-clerk-docs/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search Clerk Docs" 2 | description = "Command to search through Clerk documentation and open them in your browser." 3 | endpointURL = "https://slapcommands.vercel.app/api/docsearch/clerk" 4 | sourceCodeURL = "https://github.com/AnishDe12020/slapcommands/blob/main/src/shared/docsearch/clerk-docs.js" 5 | language = "javascript" 6 | categories = ["Developer Tools", "Productivity", "Documentation"] 7 | 8 | author.name = "Anish De" 9 | author.profileURL = "https://github.com/AnishDe12020" 10 | 11 | readme = """ 12 | This command lets you search through the [Clerk documentation](https://docs.clerk.dev/). You can also copy the URL to the individual pages or paste it to your current application. 13 | 14 | The command is also [available](https://github.com/AnishDe12020/slapcommands) as a Local Command. 15 | """ 16 | -------------------------------------------------------------------------------- /commands/search-clerk-docs/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commands/search-emojis/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-emojis -------------------------------------------------------------------------------- /commands/search-emojis/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search Emojis" 2 | description = "Search through emojis and paste them to current applciation" 3 | endpointURL = "https://slapcommands.vercel.app/api/utils/emoji-paster" 4 | sourceCodeURL = "https://github.com/AnishDe12020/slapcommands/blob/main/src/shared/utils/emoji-paster.js" 5 | language = "javascript" 6 | categories = ["Utilities"] 7 | author.name = "Anish De" 8 | author.profileURL = "https://github.com/AnishDe12020" 9 | 10 | readme = """ 11 | The command allows you searching through emojis and pasting them to the current applciation. 12 | 13 | It is also available as a [Local Command](https://github.com/AnishDe12020/slapcommands). 14 | """ 15 | 16 | -------------------------------------------------------------------------------- /commands/search-emojis/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /commands/search-emojis/screenshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "keywords": "heart", 3 | "response": { 4 | "inputPlaceholder": "Type to search emojis", 5 | "view": { 6 | "type": "list", 7 | "ranking": false, 8 | "options": [ 9 | { 10 | "title": "Heart Suit", 11 | "subtitle": "Activities (game)", 12 | "action": { 13 | "type": "paste", 14 | "value": "♥️" 15 | }, 16 | "icon": "♥️" 17 | }, 18 | { 19 | "title": "Heart Hands", 20 | "subtitle": "People & Body (hands)", 21 | "action": { 22 | "type": "paste", 23 | "value": "🫶" 24 | }, 25 | "icon": "🫶" 26 | }, 27 | { 28 | "title": "Heart On Fire", 29 | "subtitle": "Smileys & Emotion (emotion)", 30 | "action": { 31 | "type": "paste", 32 | "value": "❤️‍🔥" 33 | }, 34 | "icon": "❤️‍🔥" 35 | }, 36 | { 37 | "title": "Red Heart", 38 | "subtitle": "Smileys & Emotion (emotion)", 39 | "action": { 40 | "type": "paste", 41 | "value": "❤️" 42 | }, 43 | "icon": "❤️" 44 | }, 45 | { 46 | "title": "Two Hearts", 47 | "subtitle": "Smileys & Emotion (emotion)", 48 | "action": { 49 | "type": "paste", 50 | "value": "💕" 51 | }, 52 | "icon": "💕" 53 | }, 54 | { 55 | "title": "Blue Heart", 56 | "subtitle": "Smileys & Emotion (emotion)", 57 | "action": { 58 | "type": "paste", 59 | "value": "💙" 60 | }, 61 | "icon": "💙" 62 | }, 63 | { 64 | "title": "Heart With Arrow", 65 | "subtitle": "Smileys & Emotion (emotion)", 66 | "action": { 67 | "type": "paste", 68 | "value": "💘" 69 | }, 70 | "icon": "💘" 71 | }, 72 | { 73 | "title": "Heart Decoration", 74 | "subtitle": "Smileys & Emotion (emotion)", 75 | "action": { 76 | "type": "paste", 77 | "value": "💟" 78 | }, 79 | "icon": "💟" 80 | }, 81 | { 82 | "title": "Brown Heart", 83 | "subtitle": "Smileys & Emotion (emotion)", 84 | "action": { 85 | "type": "paste", 86 | "value": "🤎" 87 | }, 88 | "icon": "🤎" 89 | }, 90 | { 91 | "title": "Heart Exclamation", 92 | "subtitle": "Smileys & Emotion (emotion)", 93 | "action": { 94 | "type": "paste", 95 | "value": "❣️" 96 | }, 97 | "icon": "❣️" 98 | }, 99 | { 100 | "title": "White Heart", 101 | "subtitle": "Smileys & Emotion (emotion)", 102 | "action": { 103 | "type": "paste", 104 | "value": "🤍" 105 | }, 106 | "icon": "🤍" 107 | }, 108 | { 109 | "title": "Heart With Ribbon", 110 | "subtitle": "Smileys & Emotion (emotion)", 111 | "action": { 112 | "type": "paste", 113 | "value": "💝" 114 | }, 115 | "icon": "💝" 116 | }, 117 | { 118 | "title": "Green Heart", 119 | "subtitle": "Smileys & Emotion (emotion)", 120 | "action": { 121 | "type": "paste", 122 | "value": "💚" 123 | }, 124 | "icon": "💚" 125 | }, 126 | { 127 | "title": "Black Heart", 128 | "subtitle": "Smileys & Emotion (emotion)", 129 | "action": { 130 | "type": "paste", 131 | "value": "🖤" 132 | }, 133 | "icon": "🖤" 134 | }, 135 | { 136 | "title": "Orange Heart", 137 | "subtitle": "Smileys & Emotion (emotion)", 138 | "action": { 139 | "type": "paste", 140 | "value": "🧡" 141 | }, 142 | "icon": "🧡" 143 | }, 144 | { 145 | "title": "Yellow Heart", 146 | "subtitle": "Smileys & Emotion (emotion)", 147 | "action": { 148 | "type": "paste", 149 | "value": "💛" 150 | }, 151 | "icon": "💛" 152 | }, 153 | { 154 | "title": "Purple Heart", 155 | "subtitle": "Smileys & Emotion (emotion)", 156 | "action": { 157 | "type": "paste", 158 | "value": "💜" 159 | }, 160 | "icon": "💜" 161 | }, 162 | { 163 | "title": "Broken Heart", 164 | "subtitle": "Smileys & Emotion (emotion)", 165 | "action": { 166 | "type": "paste", 167 | "value": "💔" 168 | }, 169 | "icon": "💔" 170 | }, 171 | { 172 | "title": "Mending Heart", 173 | "subtitle": "Smileys & Emotion (emotion)", 174 | "action": { 175 | "type": "paste", 176 | "value": "❤️‍🩹" 177 | }, 178 | "icon": "❤️‍🩹" 179 | }, 180 | { 181 | "title": "Beating Heart", 182 | "subtitle": "Smileys & Emotion (emotion)", 183 | "action": { 184 | "type": "paste", 185 | "value": "💓" 186 | }, 187 | "icon": "💓" 188 | }, 189 | { 190 | "title": "Growing Heart", 191 | "subtitle": "Smileys & Emotion (emotion)", 192 | "action": { 193 | "type": "paste", 194 | "value": "💗" 195 | }, 196 | "icon": "💗" 197 | }, 198 | { 199 | "title": "Sparkling Heart", 200 | "subtitle": "Smileys & Emotion (emotion)", 201 | "action": { 202 | "type": "paste", 203 | "value": "💖" 204 | }, 205 | "icon": "💖" 206 | }, 207 | { 208 | "title": "Revolving Hearts", 209 | "subtitle": "Smileys & Emotion (emotion)", 210 | "action": { 211 | "type": "paste", 212 | "value": "💞" 213 | }, 214 | "icon": "💞" 215 | }, 216 | { 217 | "title": "Anatomical Heart", 218 | "subtitle": "People & Body (body-parts)", 219 | "action": { 220 | "type": "paste", 221 | "value": "🫀" 222 | }, 223 | "icon": "🫀" 224 | }, 225 | { 226 | "title": "Heart Hands: Dark Skin Tone", 227 | "subtitle": "People & Body (hands)", 228 | "action": { 229 | "type": "paste", 230 | "value": "🫶🏿" 231 | }, 232 | "icon": "🫶🏿" 233 | }, 234 | { 235 | "title": "Heart Hands: Light Skin Tone", 236 | "subtitle": "People & Body (hands)", 237 | "action": { 238 | "type": "paste", 239 | "value": "🫶🏻" 240 | }, 241 | "icon": "🫶🏻" 242 | }, 243 | { 244 | "title": "Heart Hands: Medium Skin Tone", 245 | "subtitle": "People & Body (hands)", 246 | "action": { 247 | "type": "paste", 248 | "value": "🫶🏽" 249 | }, 250 | "icon": "🫶🏽" 251 | }, 252 | { 253 | "title": "Couple With Heart", 254 | "subtitle": "People & Body (family)", 255 | "action": { 256 | "type": "paste", 257 | "value": "💑" 258 | }, 259 | "icon": "💑" 260 | }, 261 | { 262 | "title": "Heart Hands: Medium-dark Skin Tone", 263 | "subtitle": "People & Body (hands)", 264 | "action": { 265 | "type": "paste", 266 | "value": "🫶🏾" 267 | }, 268 | "icon": "🫶🏾" 269 | }, 270 | { 271 | "title": "Heart Hands: Medium-light Skin Tone", 272 | "subtitle": "People & Body (hands)", 273 | "action": { 274 | "type": "paste", 275 | "value": "🫶🏼" 276 | }, 277 | "icon": "🫶🏼" 278 | }, 279 | { 280 | "title": "Couple With Heart: Man, Man", 281 | "subtitle": "People & Body (family)", 282 | "action": { 283 | "type": "paste", 284 | "value": "👨‍❤️‍👨" 285 | }, 286 | "icon": "👨‍❤️‍👨" 287 | }, 288 | { 289 | "title": "Couple With Heart: Woman, Man", 290 | "subtitle": "People & Body (family)", 291 | "action": { 292 | "type": "paste", 293 | "value": "👩‍❤️‍👨" 294 | }, 295 | "icon": "👩‍❤️‍👨" 296 | }, 297 | { 298 | "title": "Smiling Face With Hearts", 299 | "subtitle": "Smileys & Emotion (face-affection)", 300 | "action": { 301 | "type": "paste", 302 | "value": "🥰" 303 | }, 304 | "icon": "🥰" 305 | }, 306 | { 307 | "title": "Couple With Heart: Woman, Woman", 308 | "subtitle": "People & Body (family)", 309 | "action": { 310 | "type": "paste", 311 | "value": "👩‍❤️‍👩" 312 | }, 313 | "icon": "👩‍❤️‍👩" 314 | }, 315 | { 316 | "title": "Smiling Cat With Heart-eyes", 317 | "subtitle": "Smileys & Emotion (cat-face)", 318 | "action": { 319 | "type": "paste", 320 | "value": "😻" 321 | }, 322 | "icon": "😻" 323 | }, 324 | { 325 | "title": "Couple With Heart: Dark Skin Tone", 326 | "subtitle": "People & Body (family)", 327 | "action": { 328 | "type": "paste", 329 | "value": "💑🏿" 330 | }, 331 | "icon": "💑🏿" 332 | }, 333 | { 334 | "title": "Couple With Heart: Light Skin Tone", 335 | "subtitle": "People & Body (family)", 336 | "action": { 337 | "type": "paste", 338 | "value": "💑🏻" 339 | }, 340 | "icon": "💑🏻" 341 | }, 342 | { 343 | "title": "Smiling Face With Heart-eyes", 344 | "subtitle": "Smileys & Emotion (face-affection)", 345 | "action": { 346 | "type": "paste", 347 | "value": "😍" 348 | }, 349 | "icon": "😍" 350 | }, 351 | { 352 | "title": "Couple With Heart: Medium Skin Tone", 353 | "subtitle": "People & Body (family)", 354 | "action": { 355 | "type": "paste", 356 | "value": "💑🏽" 357 | }, 358 | "icon": "💑🏽" 359 | } 360 | ] 361 | } 362 | } 363 | } -------------------------------------------------------------------------------- /commands/search-honeycomb-boards/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-honeycomb-boards -------------------------------------------------------------------------------- /commands/search-honeycomb-boards/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search Honeycomb Boards" 2 | description = "Quickly jump to your team's Honeycomb Boards" 3 | endpointURL = "https://www.taraszubyk.com/api/slapdash/honeycomb-boards" 4 | sourceCodeURL = "https://github.com/zuta/slapdash-commands/blob/master/api/slapdash/honeycomb-boards.ts" 5 | language = "typescript" 6 | categories = ["Developer Tools"] 7 | 8 | author.name = "Taras Zubyk" 9 | author.profileURL = "https://twitter.com/_zuta_" 10 | 11 | readme = """ 12 | When you run the command for the first time, it will ask you to provide an API Key to access your 13 | team's [Honeycomb Boards](https://honeycomb.io/). You can generate a new API Key on your team's [Settings Page in Honeycomb](https://ui.honeycomb.io/teams). 14 | Make sure to enable access to Honeycomb Boards when creating the key. 15 | 16 | Once the command is set up, you will see a list of Honeycomb Boards for your team. Each option 17 | in the list represents a single Honeycomb Board giving you some additional information about the charts that the board contains. 18 | """ -------------------------------------------------------------------------------- /commands/search-honeycomb-boards/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /commands/search-honeycomb-boards/screenshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "keywords": "p", 3 | "response": { 4 | "view": { 5 | "type": "list", 6 | "options": [ 7 | { 8 | "title": "Webhooks snippets", 9 | "subtitle": ["index-app-full vs. webhook calls for a cred"], 10 | "icon": { 11 | "monochrome": "" 12 | }, 13 | "action": { 14 | "type": "open-url", 15 | "url": "https://ui.honeycomb.io/slapdash/board/zpPW5ufAkyC" 16 | } 17 | }, 18 | { 19 | "title": "Product Analytics", 20 | "subtitle": ["Funnel", "Pages", "Client Errors"], 21 | "icon": { 22 | "monochrome": "" 23 | }, 24 | "action": { 25 | "type": "open-url", 26 | "url": "https://ui.honeycomb.io/slapdash/board/dBkJnZpMUWu" 27 | } 28 | }, 29 | { 30 | "title": "Site Performance", 31 | "subtitle": ["GraphQL Queries", "React App Perf"], 32 | "icon": { 33 | "monochrome": "" 34 | }, 35 | "action": { 36 | "type": "open-url", 37 | "url": "https://ui.honeycomb.io/slapdash/board/idjaeVL7peA" 38 | } 39 | }, 40 | { 41 | "title": "Indexing Health", 42 | "subtitle": [], 43 | "icon": { 44 | "monochrome": "" 45 | }, 46 | "action": { 47 | "type": "open-url", 48 | "url": "https://ui.honeycomb.io/slapdash/board/ywUo9a7vDFN" 49 | } 50 | }, 51 | { 52 | "title": "RestClient", 53 | "subtitle": [], 54 | "icon": { 55 | "monochrome": "" 56 | }, 57 | "action": { 58 | "type": "open-url", 59 | "url": "https://ui.honeycomb.io/slapdash/board/jpiL34oYVtN" 60 | } 61 | }, 62 | { 63 | "title": "Housekeeping", 64 | "subtitle": [], 65 | "icon": { 66 | "monochrome": "" 67 | }, 68 | "action": { 69 | "type": "open-url", 70 | "url": "https://ui.honeycomb.io/slapdash/board/ooHyXjZ53sC" 71 | } 72 | }, 73 | { 74 | "title": "Indexing Jobs", 75 | "subtitle": [], 76 | "icon": { 77 | "monochrome": "" 78 | }, 79 | "action": { 80 | "type": "open-url", 81 | "url": "https://ui.honeycomb.io/slapdash/board/XH3hVGxZej" 82 | } 83 | }, 84 | { 85 | "title": "Memory, Facts, Backoff", 86 | "subtitle": ["Worker mem", "Applied fact per cred"], 87 | "icon": { 88 | "monochrome": "" 89 | }, 90 | "action": { 91 | "type": "open-url", 92 | "url": "https://ui.honeycomb.io/slapdash/board/8fncorYfVuC" 93 | } 94 | } 95 | ] 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /commands/search-iconfinder/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-iconfinder -------------------------------------------------------------------------------- /commands/search-iconfinder/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search Iconfinder" 2 | description = "Search for icons from Iconfinder and copy & paste them directly to other apps." 3 | endpointURL = "https://www.taraszubyk.com/api/slapdash/iconfinder" 4 | sourceCodeURL = "https://github.com/zuta/slapdash-commands/blob/master/api/slapdash/iconfinder.ts" 5 | language = "typescript" 6 | categories = ["Design"] 7 | 8 | author.name = "Taras Zubyk" 9 | author.profileURL = "https://twitter.com/_zuta_" 10 | 11 | readme = """ 12 | The command lets you quickly search icons from [Iconfinder](https://www.iconfinder.com/). 13 | 14 | The first time you run the command, you will be asked to set up some search filters. For instance, 15 | you'll be able to choose whether to include Premium icons or limit your search to Vector icons only. 16 | Once the command is configured, you can start searching the icons by typing the keywords into the Command Bar's input field. 17 | 18 | For Vector icons, when you press `ENTER` the icon is pasted directly into the active app. It works great with design tools such as [Figma](https://figma.com/). 19 | Pressing `TAB` will give you more options to choose from, e.g. open the icon page in [Iconfinder]((https://www.iconfinder.com/)) or copy the URL. 20 | """ -------------------------------------------------------------------------------- /commands/search-iconfinder/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /commands/search-nextjs-docs/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-nextjs-docs -------------------------------------------------------------------------------- /commands/search-nextjs-docs/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search Next.js Docs" 2 | description = "Command to search through Next.js documentation and open them in your browser." 3 | endpointURL = "https://slapcommands.vercel.app/api/docsearch/next-js" 4 | sourceCodeURL = "https://github.com/AnishDe12020/slapcommands/blob/main/src/shared/docsearch/nextjs-docs.js" 5 | language = "javascript" 6 | categories = ["Developer Tools", "Productivity", "Documentation"] 7 | 8 | author.name = "Anish De" 9 | author.profileURL = "https://github.com/AnishDe12020" 10 | 11 | readme = """ 12 | This command lets you search through the [Next.js documentation](https://nextjs.org/docs). You can also copy the URL to the individual pages or paste it to your current application. 13 | 14 | The command is also [available](https://github.com/AnishDe12020/slapcommands) as a Local Command. 15 | """ 16 | -------------------------------------------------------------------------------- /commands/search-nextjs-docs/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commands/search-npm/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-npm -------------------------------------------------------------------------------- /commands/search-npm/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search NPM" 2 | description = "Quickly search node packages on NPM" 3 | endpointURL = "https://www.taraszubyk.com/api/slapdash/search-npm" 4 | sourceCodeURL = "https://github.com/zuta/slapdash-commands/blob/master/api/slapdash/search-npm.ts" 5 | language = "typescript" 6 | categories = ["Developer Tools"] 7 | 8 | author.name = "Taras Zubyk" 9 | author.profileURL = "https://twitter.com/_zuta_" 10 | 11 | readme = """ 12 | The command lets you search node packages from the [NPM Registry](https://www.npmjs.com/). 13 | 14 | It is built on top of the [npms API](https://npms.io/). In addition to Github Stars, each package will have the scores for Popularity, Quality and 15 | Maintenance. These should help you evaluate the health and freshness of the package. If you're curious how these scores are calculated check out npms [About Page](https://npms.io/about). 16 | 17 | Pressing `ENTER` will open a package on NPM, but if you want to jump to the package repository or its home page, press `TAB` instead and choose the option you want. 18 | """ -------------------------------------------------------------------------------- /commands/search-npm/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commands/search-slapdash-platform-docs/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-slapdash-platform-docs -------------------------------------------------------------------------------- /commands/search-slapdash-platform-docs/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search Slapdash Platform Docs" 2 | description = "Search through Slapdash Platform documentation" 3 | endpointURL = "https://slapcommands.vercel.app/api/docsearch/slapdash-platform" 4 | sourceCodeURL = "https://github.com/AnishDe12020/slapcommands/blob/main/src/shared/docsearch/slapdash-platform-docs.js" 5 | language = "javascript" 6 | categories = ["Developer Tools", "Documentation"] 7 | 8 | author.name = "Anish De" 9 | author.profileURL = "https://github.com/AnishDe12020" 10 | 11 | readme = """ 12 | The command lets you search through the [Slapdash Platform documentation](https://platform.slapdash.com/). You can copy the URL to the individual pages or paste it to the current application. 13 | 14 | It is also available as a [Local Command](https://github.com/AnishDe12020/slapcommands). 15 | """ 16 | -------------------------------------------------------------------------------- /commands/search-slapdash-platform-docs/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commands/search-slapdash-platform-docs/screenshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "keywords": "vi", 3 | "response": { 4 | "view": { 5 | "type": "list", 6 | "options": [ 7 | { 8 | "title": "Home", 9 | "subtitle": "", 10 | "action": { 11 | "type": "open-url", 12 | "url": "https://platform.slapdash.com/root" 13 | }, 14 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 15 | "moveAction": { 16 | "type": "add-param", 17 | "name": "item", 18 | "value": "Home&https://platform.slapdash.com/root" 19 | } 20 | }, 21 | { 22 | "title": "Cloud Commands", 23 | "subtitle": "Command Bar 101 → Cloud Commands", 24 | "action": { 25 | "type": "open-url", 26 | "url": "https://platform.slapdash.com/command-bar-101/cloud-commands" 27 | }, 28 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 29 | "moveAction": { 30 | "type": "add-param", 31 | "name": "item", 32 | "value": "Cloud Commands&https://platform.slapdash.com/command-bar-101/cloud-commands" 33 | } 34 | }, 35 | { 36 | "title": "Command Response", 37 | "subtitle": "Reference → Command Response", 38 | "action": { 39 | "type": "open-url", 40 | "url": "https://platform.slapdash.com/reference/command-response" 41 | }, 42 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 43 | "moveAction": { 44 | "type": "add-param", 45 | "name": "item", 46 | "value": "Command Response&https://platform.slapdash.com/reference/command-response" 47 | } 48 | }, 49 | { 50 | "title": "Command Response Action", 51 | "subtitle": "Reference → Command Response Action", 52 | "action": { 53 | "type": "open-url", 54 | "url": "https://platform.slapdash.com/reference/command-response-action" 55 | }, 56 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 57 | "moveAction": { 58 | "type": "add-param", 59 | "name": "item", 60 | "value": "Command Response Action&https://platform.slapdash.com/reference/command-response-action" 61 | } 62 | }, 63 | { 64 | "title": "Command Response Config", 65 | "subtitle": "Reference → Command Response Config", 66 | "action": { 67 | "type": "open-url", 68 | "url": "https://platform.slapdash.com/reference/command-response-config" 69 | }, 70 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 71 | "moveAction": { 72 | "type": "add-param", 73 | "name": "item", 74 | "value": "Command Response Config&https://platform.slapdash.com/reference/command-response-config" 75 | } 76 | }, 77 | { 78 | "title": "Command Response Icon", 79 | "subtitle": "Reference → Command Response Icon", 80 | "action": { 81 | "type": "open-url", 82 | "url": "https://platform.slapdash.com/reference/command-response-icon" 83 | }, 84 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 85 | "moveAction": { 86 | "type": "add-param", 87 | "name": "item", 88 | "value": "Command Response Icon&https://platform.slapdash.com/reference/command-response-icon" 89 | } 90 | }, 91 | { 92 | "title": "Command Response Tokens", 93 | "subtitle": "Reference → Command Response Tokens", 94 | "action": { 95 | "type": "open-url", 96 | "url": "https://platform.slapdash.com/reference/command-response-tokens" 97 | }, 98 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 99 | "moveAction": { 100 | "type": "add-param", 101 | "name": "item", 102 | "value": "Command Response Tokens&https://platform.slapdash.com/reference/command-response-tokens" 103 | } 104 | }, 105 | { 106 | "title": "Command Response View", 107 | "subtitle": "Reference → Command Response View", 108 | "action": { 109 | "type": "open-url", 110 | "url": "https://platform.slapdash.com/reference/command-response-view" 111 | }, 112 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 113 | "moveAction": { 114 | "type": "add-param", 115 | "name": "item", 116 | "value": "Command Response View&https://platform.slapdash.com/reference/command-response-view" 117 | } 118 | }, 119 | { 120 | "title": "Command Response View Form", 121 | "subtitle": "Reference → Command Response View Form", 122 | "action": { 123 | "type": "open-url", 124 | "url": "https://platform.slapdash.com/reference/command-response-view-form" 125 | }, 126 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 127 | "moveAction": { 128 | "type": "add-param", 129 | "name": "item", 130 | "value": "Command Response View Form&https://platform.slapdash.com/reference/command-response-view-form" 131 | } 132 | }, 133 | { 134 | "title": "Command Response View List", 135 | "subtitle": "Reference → Command Response View List", 136 | "action": { 137 | "type": "open-url", 138 | "url": "https://platform.slapdash.com/reference/command-response-view-list" 139 | }, 140 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 141 | "moveAction": { 142 | "type": "add-param", 143 | "name": "item", 144 | "value": "Command Response View List&https://platform.slapdash.com/reference/command-response-view-list" 145 | } 146 | }, 147 | { 148 | "title": "Command Response View Masonry", 149 | "subtitle": "Reference → Command Response View Masonry", 150 | "action": { 151 | "type": "open-url", 152 | "url": "https://platform.slapdash.com/reference/command-response-view-masonry" 153 | }, 154 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 155 | "moveAction": { 156 | "type": "add-param", 157 | "name": "item", 158 | "value": "Command Response View Masonry&https://platform.slapdash.com/reference/command-response-view-masonry" 159 | } 160 | }, 161 | { 162 | "title": "Commands", 163 | "subtitle": "Command Bar 101 → Commands", 164 | "action": { 165 | "type": "open-url", 166 | "url": "https://platform.slapdash.com/command-bar-101/commands" 167 | }, 168 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 169 | "moveAction": { 170 | "type": "add-param", 171 | "name": "item", 172 | "value": "Commands&https://platform.slapdash.com/command-bar-101/commands" 173 | } 174 | }, 175 | { 176 | "title": "Copy Special Character", 177 | "subtitle": "Command Tutorials → Copy Special Character", 178 | "action": { 179 | "type": "open-url", 180 | "url": "https://platform.slapdash.com/command-tutorials/copy-special-character" 181 | }, 182 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 183 | "moveAction": { 184 | "type": "add-param", 185 | "name": "item", 186 | "value": "Copy Special Character&https://platform.slapdash.com/command-tutorials/copy-special-character" 187 | } 188 | }, 189 | { 190 | "title": "Core Terminology", 191 | "subtitle": "Command Bar 101 → Core Terminology", 192 | "action": { 193 | "type": "open-url", 194 | "url": "https://platform.slapdash.com/command-bar-101/core-terminology" 195 | }, 196 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 197 | "moveAction": { 198 | "type": "add-param", 199 | "name": "item", 200 | "value": "Core Terminology&https://platform.slapdash.com/command-bar-101/core-terminology" 201 | } 202 | }, 203 | { 204 | "title": "Emoji Paster", 205 | "subtitle": "Command Tutorials → Emoji Paster", 206 | "action": { 207 | "type": "open-url", 208 | "url": "https://platform.slapdash.com/command-tutorials/emoji-paster" 209 | }, 210 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 211 | "moveAction": { 212 | "type": "add-param", 213 | "name": "item", 214 | "value": "Emoji Paster&https://platform.slapdash.com/command-tutorials/emoji-paster" 215 | } 216 | }, 217 | { 218 | "title": "Hooks", 219 | "subtitle": "Command Bar 101 → Hooks", 220 | "action": { 221 | "type": "open-url", 222 | "url": "https://platform.slapdash.com/command-bar-101/hooks" 223 | }, 224 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 225 | "moveAction": { 226 | "type": "add-param", 227 | "name": "item", 228 | "value": "Hooks&https://platform.slapdash.com/command-bar-101/hooks" 229 | } 230 | }, 231 | { 232 | "title": "How It Works", 233 | "subtitle": "Command Bar 101 → How It Works", 234 | "action": { 235 | "type": "open-url", 236 | "url": "https://platform.slapdash.com/command-bar-101/how-it-works" 237 | }, 238 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 239 | "moveAction": { 240 | "type": "add-param", 241 | "name": "item", 242 | "value": "How It Works&https://platform.slapdash.com/command-bar-101/how-it-works" 243 | } 244 | }, 245 | { 246 | "title": "Local Commands", 247 | "subtitle": "Command Bar 101 → Local Commands", 248 | "action": { 249 | "type": "open-url", 250 | "url": "https://platform.slapdash.com/command-bar-101/local-commands" 251 | }, 252 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 253 | "moveAction": { 254 | "type": "add-param", 255 | "name": "item", 256 | "value": "Local Commands&https://platform.slapdash.com/command-bar-101/local-commands" 257 | } 258 | }, 259 | { 260 | "title": "Publish Command", 261 | "subtitle": "Command Bar 101 → Publish Command", 262 | "action": { 263 | "type": "open-url", 264 | "url": "https://platform.slapdash.com/command-bar-101/publish-command" 265 | }, 266 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 267 | "moveAction": { 268 | "type": "add-param", 269 | "name": "item", 270 | "value": "Publish Command&https://platform.slapdash.com/command-bar-101/publish-command" 271 | } 272 | }, 273 | { 274 | "title": "Send Slack Message", 275 | "subtitle": "Command Tutorials → Send Slack Message", 276 | "action": { 277 | "type": "open-url", 278 | "url": "https://platform.slapdash.com/command-tutorials/send-slack-message" 279 | }, 280 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 281 | "moveAction": { 282 | "type": "add-param", 283 | "name": "item", 284 | "value": "Send Slack Message&https://platform.slapdash.com/command-tutorials/send-slack-message" 285 | } 286 | }, 287 | { 288 | "title": "Setup Your First Command", 289 | "subtitle": "Command Bar 101 → Setup Your First Command", 290 | "action": { 291 | "type": "open-url", 292 | "url": "https://platform.slapdash.com/command-bar-101/setup-your-first-command" 293 | }, 294 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 295 | "moveAction": { 296 | "type": "add-param", 297 | "name": "item", 298 | "value": "Setup Your First Command&https://platform.slapdash.com/command-bar-101/setup-your-first-command" 299 | } 300 | }, 301 | { 302 | "title": "Toggle Dark Mode", 303 | "subtitle": "Command Tutorials → Toggle Dark Mode", 304 | "action": { 305 | "type": "open-url", 306 | "url": "https://platform.slapdash.com/command-tutorials/toggle-dark-mode" 307 | }, 308 | "icon": "https://slapdash.com/favicon-180x180.2sB.png", 309 | "moveAction": { 310 | "type": "add-param", 311 | "name": "item", 312 | "value": "Toggle Dark Mode&https://platform.slapdash.com/command-tutorials/toggle-dark-mode" 313 | } 314 | } 315 | ] 316 | } 317 | } 318 | } -------------------------------------------------------------------------------- /commands/search-supabase-docs/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-supabase-docs 2 | -------------------------------------------------------------------------------- /commands/search-supabase-docs/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search Supabase Docs" 2 | description = "Quickly search through Supabase documentation" 3 | endpointURL = "https://slapcommands.vercel.app/api/docsearch/supabase" 4 | sourceCodeURL = "https://github.com/AnishDe12020/slapcommands/blob/main/src/shared/docsearch/supabase-docs.js" 5 | language = "javascript" 6 | categories = ["Developer Tools", "Documentation"] 7 | 8 | author.name = "Anish De" 9 | author.profileURL = "https://github.com/AnishDe12020" 10 | 11 | readme = """ 12 | This command lets you search through the [Supabase documentation](https://supabase.com/docs). You can copy the URL to the individual pages or paste it to your current application. 13 | 14 | The command is also available as a [Local Command](https://github.com/AnishDe12020/slapcommands). 15 | """ -------------------------------------------------------------------------------- /commands/search-supabase-docs/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commands/search-tailwind-css-docs/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-tailwind-css-docs -------------------------------------------------------------------------------- /commands/search-tailwind-css-docs/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search Tailwind CSS Docs" 2 | description = "Command to search through Tailwind CSS documentation and open them in your browser." 3 | endpointURL = "https://slapcommands.vercel.app/api/docsearch/tailwind-css" 4 | sourceCodeURL = "https://github.com/AnishDe12020/slapcommands/blob/main/src/shared/docsearch/tailwind-css-docs.js" 5 | language = "javascript" 6 | categories = ["Developer Tools", "Productivity", "Documentation"] 7 | 8 | author.name = "Anish De" 9 | author.profileURL = "https://github.com/AnishDe12020" 10 | 11 | readme = """ 12 | This command lets you search through the [Tailwind CSS documentation](https://tailwindcss.com/docs/installation). You can also copy the URL to the individual pages or paste it to your current application. 13 | 14 | The command is also [available](https://github.com/AnishDe12020/slapcommands) as a Local Command. 15 | """ 16 | -------------------------------------------------------------------------------- /commands/search-tailwind-css-docs/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commands/search-unsplash/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/search-unsplash -------------------------------------------------------------------------------- /commands/search-unsplash/command.toml: -------------------------------------------------------------------------------- 1 | name = "Search Unsplash" 2 | description = "Search free high-quality photos from Unsplash" 3 | endpointURL = "https://www.taraszubyk.com/api/slapdash/unsplash-search" 4 | sourceCodeURL = "https://github.com/zuta/slapdash-commands/blob/master/api/slapdash/unsplash-search.ts" 5 | language = "typescript" 6 | categories = ["Design"] 7 | 8 | author.name = "Taras Zubyk" 9 | author.profileURL = "https://twitter.com/_zuta_" 10 | 11 | readme = """ 12 | Use this command to search free, high-resolution photos from [Unsplash](https://unsplash.com/). 13 | Simply type the keywords and jump to the photo you liked. A very useful tool when preparing a presentation or writing a blog post. 14 | 15 | All photos are displayed in the [Pinterest](https://pinterest.com/)-like layout – Masonry View - which gives you a beautiful preview of each photo. 16 | """ -------------------------------------------------------------------------------- /commands/search-unsplash/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /commands/show-current-unix-timestamp/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/show-current-unix-timestamp -------------------------------------------------------------------------------- /commands/show-current-unix-timestamp/command.toml: -------------------------------------------------------------------------------- 1 | name = "Show Current UNIX Timestamp" 2 | description = "Quickly see or copy the current UNIX timestamp" 3 | endpointURL = "https://slapcommands.vercel.app/api/utils/unix-timestamp" 4 | sourceCodeURL = "https://github.com/AnishDe12020/slapcommands/blob/main/src/shared/utils/unix-timestamp.js" 5 | language = "javascript" 6 | categories = ["Developer Tools", "Productivity", "Utilities"] 7 | 8 | author.name = "Anish De" 9 | author.profileURL = "https://github.com/AnishDe12020" 10 | 11 | readme = """ 12 | This command shows the current UNIX timestamp and lets you copy it to the clipboard. 13 | 14 | The command is also available as a [Local Command](https://github.com/AnishDe12020/slapcommands). 15 | """ 16 | 17 | -------------------------------------------------------------------------------- /commands/show-current-unix-timestamp/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commands/show-current-unix-timestamp/screenshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "keywords": "", 3 | "response": { 4 | "view": { 5 | "type": "list", 6 | "options": [ 7 | { 8 | "title": "Copy Timestamp", 9 | "action": { 10 | "type": "copy", 11 | "value": "1649154513" 12 | }, 13 | "subtitle": ["1649154513", "Tue Apr 05 2022 10:28:33 GMT+0000 (Coordinated Universal Time)"] 14 | } 15 | ] 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /commands/vercel-projects/README.md: -------------------------------------------------------------------------------- 1 | https://slapdash.com/commands/vercel-projects -------------------------------------------------------------------------------- /commands/vercel-projects/command.toml: -------------------------------------------------------------------------------- 1 | name = "Vercel Projects" 2 | description = "Quickly search & jump to a Vercel project." 3 | endpointURL = "https://www.taraszubyk.com/api/slapdash/vercel-projects" 4 | sourceCodeURL = "https://github.com/zuta/slapdash-commands/blob/master/api/slapdash/vercel-projects.ts" 5 | language = "typescript" 6 | categories = ["Developer Tools"] 7 | 8 | author.name = "Taras Zubyk" 9 | author.profileURL = "https://twitter.com/_zuta_" 10 | 11 | readme = """ 12 | The command gets you to your [Vercel](https://vercel.com/) project in a blink of an eye. 13 | 14 | First, provide the access token that you can create on the [Vercel account page](https://vercel.com/account/tokens), then 15 | run the command, type the project's name and press `ENTER`. 16 | 17 | If you want to jump to the latest project's deployment instead, press `TAB` and you'll have options to open it in the browser or copy its URL. 18 | """ -------------------------------------------------------------------------------- /commands/vercel-projects/icon.monochrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /commands/vercel-projects/screenshot.json: -------------------------------------------------------------------------------- 1 | { 2 | "keywords": "dem", 3 | "response": { 4 | "view": { 5 | "type": "list", 6 | "options": [ 7 | { 8 | "title": "personal", 9 | "subtitle": [ 10 | "Other", 11 | "9/18/2021, 1:08 PM" 12 | ], 13 | "icon": "https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/other.svg", 14 | "action": { 15 | "type": "open-url", 16 | "url": "https://vercel.com/7UAPNpiiUIMtL4zu7SUB3PH7/personal" 17 | }, 18 | "moveAction": { 19 | "type": "add-param", 20 | "name": "project", 21 | "value": "prj_vCyLt3GKoeU42uqYUMZnejF3CCT7" 22 | } 23 | }, 24 | { 25 | "title": "slapdash-commands", 26 | "subtitle": [ 27 | "Other", 28 | "8/23/2021, 3:49 PM" 29 | ], 30 | "icon": "https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/other.svg", 31 | "action": { 32 | "type": "open-url", 33 | "url": "https://vercel.com/7UAPNpiiUIMtL4zu7SUB3PH7/slapdash-commands" 34 | }, 35 | "moveAction": { 36 | "type": "add-param", 37 | "name": "project", 38 | "value": "prj_4wXdt9R4apulKVNcaNMBigynhvGk" 39 | } 40 | }, 41 | { 42 | "title": "create-react-app-demo", 43 | "subtitle": [ 44 | "Create React App", 45 | "8/22/2021, 5:05 PM" 46 | ], 47 | "icon": "https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/react.svg", 48 | "action": { 49 | "type": "open-url", 50 | "url": "https://vercel.com/7UAPNpiiUIMtL4zu7SUB3PH7/create-react-app-demo" 51 | }, 52 | "moveAction": { 53 | "type": "add-param", 54 | "name": "project", 55 | "value": "prj_8LBYKa2K7xOgAgD3Bnvja2i3GL9v" 56 | } 57 | }, 58 | { 59 | "title": "vite-vercel-demo", 60 | "subtitle": [ 61 | "Vite", 62 | "8/11/2021, 1:27 PM" 63 | ], 64 | "icon": "https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/vite.svg", 65 | "action": { 66 | "type": "open-url", 67 | "url": "https://vercel.com/7UAPNpiiUIMtL4zu7SUB3PH7/vite-vercel-demo" 68 | }, 69 | "moveAction": { 70 | "type": "add-param", 71 | "name": "project", 72 | "value": "prj_Ild3OBfVZPzyXdCVMj51xUVCoBSY" 73 | } 74 | }, 75 | { 76 | "title": "nextjs-vercel-demo", 77 | "subtitle": [ 78 | "Next.js", 79 | "8/11/2021, 1:13 PM" 80 | ], 81 | "icon": "https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/next.svg", 82 | "action": { 83 | "type": "open-url", 84 | "url": "https://vercel.com/7UAPNpiiUIMtL4zu7SUB3PH7/nextjs-vercel-demo" 85 | }, 86 | "moveAction": { 87 | "type": "add-param", 88 | "name": "project", 89 | "value": "prj_Uy5WADx4WeztDYTfLRqbyWIORjCw" 90 | } 91 | } 92 | ] 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /docs/.gitbook/assets/cleanshot-2021-08-20-at-16.22.14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/cleanshot-2021-08-20-at-16.22.14.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/cleanshot-2021-08-20-at-16.27.46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/cleanshot-2021-08-20-at-16.27.46.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/command-fux.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/command-fux.gif -------------------------------------------------------------------------------- /docs/.gitbook/assets/copy-special-character.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/copy-special-character.gif -------------------------------------------------------------------------------- /docs/.gitbook/assets/emoji-paster.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/emoji-paster.gif -------------------------------------------------------------------------------- /docs/.gitbook/assets/image (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/image (1).png -------------------------------------------------------------------------------- /docs/.gitbook/assets/image (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/image (2).png -------------------------------------------------------------------------------- /docs/.gitbook/assets/image (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/image (3).png -------------------------------------------------------------------------------- /docs/.gitbook/assets/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/image.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-11-at-8.26.45-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-11-at-8.26.45-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-11-at-8.27.53-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-11-at-8.27.53-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-11-at-8.28.24-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-11-at-8.28.24-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-11-at-8.28.52-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-11-at-8.28.52-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-11-at-8.30.10-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-11-at-8.30.10-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-11-at-8.31.38-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-11-at-8.31.38-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-15-at-5.37.17-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-15-at-5.37.17-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-15-at-5.38.22-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-15-at-5.38.22-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-15-at-5.40.26-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-15-at-5.40.26-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-18-at-1.38.33-am.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-18-at-1.38.33-am.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-18-at-3.10.48-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-18-at-3.10.48-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-20-at-2.29.56-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-20-at-2.29.56-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-20-at-2.31.40-pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-20-at-2.31.40-pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen-shot-2021-06-21-at-12.16.21-am.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen-shot-2021-06-21-at-12.16.21-am.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen_shot_2021-05-19_at_11.25.08_pm (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen_shot_2021-05-19_at_11.25.08_pm (1).png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen_shot_2021-05-19_at_11.25.08_pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen_shot_2021-05-19_at_11.25.08_pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen_shot_2021-05-19_at_11.26.46_pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen_shot_2021-05-19_at_11.26.46_pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen_shot_2021-05-23_at_3.35.09_pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen_shot_2021-05-23_at_3.35.09_pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/screen_shot_2021-05-25_at_10.19.37_pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/screen_shot_2021-05-25_at_10.19.37_pm.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/send-slack-message.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/send-slack-message.gif -------------------------------------------------------------------------------- /docs/.gitbook/assets/test-1-.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/test-1-.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/test.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/toggle-dark-mode (1) (2) (2) (2) (1).gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/toggle-dark-mode (1) (2) (2) (2) (1).gif -------------------------------------------------------------------------------- /docs/.gitbook/assets/toggle-dark-mode (1) (2) (2) (2) (2) (1).gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/toggle-dark-mode (1) (2) (2) (2) (2) (1).gif -------------------------------------------------------------------------------- /docs/.gitbook/assets/toggle-dark-mode (1) (2) (2) (2) (2) (2).gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/toggle-dark-mode (1) (2) (2) (2) (2) (2).gif -------------------------------------------------------------------------------- /docs/.gitbook/assets/toggle-dark-mode (1) (2) (2) (2) (2).gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/toggle-dark-mode (1) (2) (2) (2) (2).gif -------------------------------------------------------------------------------- /docs/.gitbook/assets/toggle-dark-mode (1) (2) (2) (2).gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slapdash/platform/ce3cec4dee4ba863090b2129844b7d755cd74604/docs/.gitbook/assets/toggle-dark-mode (1) (2) (2) (2).gif -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Ahoy, world!](root.md) 4 | 5 | ## Command Bar 101 6 | 7 | * [How it Works](command-bar-101/how-it-works.md) 8 | * [Core Terminology](command-bar-101/core-terminology.md) 9 | * [Commands](command-bar-101/commands.md) 10 | * [Local Commands](command-bar-101/local-commands.md) 11 | * [Cloud Commands](command-bar-101/cloud-commands.md) 12 | * [Build Your First Command](command-bar-101/setup-your-first-command.md) 13 | * [Publish Command](command-bar-101/publish-command.md) 14 | * [Hooks](command-bar-101/hooks.md) 15 | 16 | ## Command Tutorials 17 | 18 | * [Toggle Dark Mode](command-tutorials/toggle-dark-mode.md) 19 | * [Emoji Paster](command-tutorials/emoji-paster.md) 20 | * [Copy Special Character](command-tutorials/copy-special-character.md) 21 | * [Send Slack Message](command-tutorials/send-slack-message.md) 22 | 23 | ## Reference 24 | 25 | * [Command Response](reference/command-response.md) 26 | * [Action](reference/command-response-action.md) 27 | * [View](reference/command-response-view.md) 28 | * [List View](reference/command-response-view-list.md) 29 | * [Masonry View](reference/command-response-view-masonry.md) 30 | * [Form View](reference/command-response-view-form.md) 31 | * [Tokens](reference/command-response-tokens.md) 32 | * [Icon](reference/command-response-icon.md) 33 | * [Config](reference/command-response-config.md) 34 | -------------------------------------------------------------------------------- /docs/command-bar-101/cloud-commands.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Commands that are hosted on the web. 3 | --- 4 | 5 | # Cloud Commands 6 | 7 | Cloud commands are hosted at URL endpoints. Slapdash makes HTTPS requests to the endpoint and interprets the JSON-encoded [Command Response](../reference/command-response.md).\ 8 | \ 9 | Commands that run in the cloud can't make any changes to your computer (it's just JSON over HTTPS after all), so they are a safe way to share Command Bar functionality with others. 10 | 11 | ## Create Cloud Command 12 | 13 | To create a cloud command, run **Create Command** in the Command Bar, choose **Cloud** as a type, paste the **Endpoint URL** of your command, give it a name and press **Create Command**. 14 | 15 | ![](../.gitbook/assets/cleanshot-2021-08-20-at-16.22.14.png) 16 | 17 | ## Developing & Deploying with Replit 18 | 19 | One of our favourite ways to host and develop cloud commands is with [Replit](https://replit.com).\ 20 | \ 21 | We like it because we can use any programming language to write the command, and we can do the development directly in the browser. It's a super quick way to get an HTTPS endpoint up and running with just a few clicks.\ 22 | \ 23 | **Fork Example** 24 | 25 | The fastest way to start is to fork another Repl. Here are a few examples you can choose from: 26 | 27 | * [Basic Python Example](https://replit.com/@slapdash/slapdash-command-python) 28 | * [Send Slack Message](https://replit.com/@slapdash/send-slack-message) 29 | 30 | **Run Command** 31 | 32 | After forking the Repl, hit the **Run** button to make sure the associated HTTPS endpoint is accessible.\ 33 | \ 34 | Find the endpoint URL in the top-right panel. This is the URL you will use to create the command inside Slapdash. 35 | 36 | ![](../.gitbook/assets/screen-shot-2021-06-18-at-3.10.48-pm.png) 37 | 38 | \ 39 | **Deploying & Sharing Command**\ 40 | By default, Repls aren't always running. If you plan to use the command often or to share it with others, you'll need to make sure the Repl is set to be **Always On.** 41 | 42 | ## Deploying with Vercel 43 | 44 | You can also use Vercel to deploy a command as a [Serverless Function](https://vercel.com/docs/serverless-functions/introduction). 45 | 46 | Start by creating a **New Project** inside Vercel and choose the **NextJS template**. 47 | 48 | Create a new file in the project under `pages/api/ahoy-world.js`. 49 | 50 | Then, add the following sample code and push to your repository to deploy it. 51 | 52 | ```javascript 53 | module.exports = async (req, res) => { 54 | const response = { 55 | view: { 56 | type: "list", 57 | options: [ 58 | { 59 | title: "Open Slapdash", 60 | action: { 61 | type: "open-url", 62 | url: "https://slapdash.com" 63 | } 64 | }, 65 | { 66 | title: "Copy Heart Emoji", 67 | action: { 68 | type: "copy", 69 | value: "❤️" 70 | } 71 | } 72 | ] 73 | } 74 | }; 75 | res.setHeader("Access-Control-Allow-Headers", "*"); // for config headers 76 | res.setHeader("Access-Control-Allow-Origin", "*"); 77 | res.json(response); 78 | } 79 | ``` 80 | 81 | At this stage, you should have a functioning URL like `https://nextjs-***.vercel.app/api/ahoy-world` that you can use to create a command in Slapdash. 82 | -------------------------------------------------------------------------------- /docs/command-bar-101/commands.md: -------------------------------------------------------------------------------- 1 | # Commands 2 | 3 | The easiest way to think about commands is as functions. As a function, it can accept arguments as input and can return some output. 4 | 5 | ``` 6 | Command(Input) -> Output 7 | ``` 8 | 9 | Like a function, a command doesn't have to return anything. Imagine a command to put your computer to sleep: there is no output that's needed.\ 10 | \ 11 | However, most commands have an output, which tells Slapdash what to do or show in the Command Bar.\ 12 | \ 13 | This output is a JSON-serialized data structure that conforms to the [Command Response Specification](../reference/command-response.md). 14 | 15 | You can use it to tell Slapdash to [copy something](../reference/command-response-action.md#actioncopy) to the clipboard, [open a URL](../reference/command-response-action.md#actionopenurl) in a browser, [show a form](../reference/command-response-view-form.md) to someone, or present an [interactive list view](../reference/command-response-view-list.md). 16 | 17 | ### Local vs. Cloud Commands 18 | 19 | There are two types of commands: [Local Commands](local-commands.md), which are scripts that run on your computer, and [Cloud Commands](cloud-commands.md), which are commands that are hosted on the web. 20 | 21 | They are mostly the same, but they do offer some trade-offs: 22 | 23 | | Local Commands | Cloud Commands | 24 | | --------------------------------- | --------------------------------- | 25 | | Script on your computer | Accessible by URL | 26 | | Can do whatever your computer can | No direct access to your computer | 27 | | Not shareable with team | Shareable with team | 28 | | Great for development | Great for production deployment | 29 | | Works offline | Unlimited compute | 30 | 31 | When developing a new command, Local Commands are the fastest and simplest way to get things going. 32 | 33 | ### How Commands are Run 34 | 35 | Local Commands are just scripts that are run on your computer. Slapdash uses stdin to send arguments to the command and interprets the stdout, expecting it to be a JSON [Command Response](../reference/command-response.md).\ 36 | \ 37 | Cloud Commands are run by making a request to an HTTPS endpoint. Slapdash passes arguments to the command using RESTful conventions. Slapdash interprets the HTTPS response, expecting it to be a JSON Command Response. 38 | 39 | ![](../.gitbook/assets/test-1-.png) 40 | -------------------------------------------------------------------------------- /docs/command-bar-101/core-terminology.md: -------------------------------------------------------------------------------- 1 | # Core Terminology 2 | 3 | ## Input and View 4 | 5 | When the Command Bar is open, there are two parts: the **Input** and the **View**. The Input is where you type and the View shows the UI, which reacts to what’s typed inside the input. 6 | 7 | Here’s an example of a Command Bar that has an Input, a math expression, and a View, the calculated result of the expression. 8 | 9 | ![](../.gitbook/assets/test.png) 10 | 11 | ## Options 12 | 13 | Although the View can technically be anything, most often it is built with a collection of UI components called an **Option**. 14 | 15 | Each Option has an Action associated with, which is performed by hitting **`Enter`** with the Option selected. An action can be something like: 16 | 17 | * Open a URL 18 | * Copy text to Clipboard 19 | * Open an application 20 | * Run a script on the computer 21 | 22 | Traditionally, the set of Options displayed in the view are based on the Input. By default, the Command Bar will fuzzy search the displayed Options, showing only ones that match. 23 | 24 | Every Option has an Action, but some options may also have a **Move Action**. The Move Action is activated by hitting **`Tab`** and it moves the person to a different location in the Command Bar. 25 | 26 | ## Location 27 | 28 | The Command Bar has a notion of location, or an address. Similar to how a browser has the address of which page is open. For every address, there is a Command that is responsible for generating the View. 29 | 30 | Even when you first open the Command Bar, it points to a special location: root. Under the hood, there is a command, managed by Slapdash, that is responsible for generating the UI for this location.\ 31 | \ 32 | In the case of the root location, Slapdash will match all your available commands, search connected applications and even parse natural language expressions. 33 | 34 | We don't have an addressing scheme yet, but the Command Bar location is visualized with pill-like tokens in the Input. 35 | 36 | ## Commands 37 | 38 | Commands are the atomic units of functionality in Slapdash. [You can think of them as functions.](commands.md)\ 39 | \ 40 | Every command you add to Slapdash will get its own unique address and show up automatically in the root view as an Option.\ 41 | \ 42 | To run a command: open the Command Bar and just type a part of its name and hit **`Enter`**. 43 | -------------------------------------------------------------------------------- /docs/command-bar-101/hooks.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Choose where your command appears 3 | --- 4 | 5 | # Hooks 6 | 7 | By default, all commands appear at the Command Bar root. However, in some cases, you may want your command to show up in another context, e.g. when there is an active web page in focus. 8 | 9 | Hooks let you achieve this. There is currently only one hook supported – URL Hook. 10 | 11 | ## URL Hook 12 | 13 | URL hook allows you to "attach" your command to the "Active Tab" group in the Command Bar. This group appears at the top of the Command Bar root when there is a browser tab in focus. 14 | 15 | !["Active Tab" group in the Command Bar](<../.gitbook/assets/image (3).png>) 16 | 17 | When your command is run, the page URL will be passed in the `url` parameter. 18 | 19 | A URL Hook is a JSON object with the following properties: 20 | 21 | | Property | Description | 22 | | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 23 | | type | **required**. The type of the hook. Must be `"url"`. | 24 | | url | The URL match pattern. Allows showing the command only when the page URL matches this pattern. For example, `https://`github`.com/*` matches HTTPS URLs only at "github.com", with any URL path and URL query string. Check out [WebExtensions Match Pattern](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns) for more examples. | 25 | 26 | #### Examples 27 | 28 | {% tabs %} 29 | {% tab title="Any URL" %} 30 | Show the command for any URL 31 | 32 | ```json 33 | { 34 | "type": "url" 35 | } 36 | ``` 37 | {% endtab %} 38 | 39 | {% tab title="Github URLs only" %} 40 | Show the command for Github URLs only 41 | 42 | ```json 43 | { 44 | "type": "url", 45 | "url": "https://github.com/*" 46 | } 47 | ``` 48 | {% endtab %} 49 | {% endtabs %} 50 | 51 | ## Define Hooks 52 | 53 | You can define Hooks using HTTP Headers for [Cloud Commands](cloud-commands.md) or code comments for [Local Commands](local-commands.md). In both cases, the hooks must be string representations of the JSON object. You can define a single Hook or multiple Hooks using an array. 54 | 55 | ### Cloud Commands 56 | 57 | Your endpoint can define Hooks by sending a custom HTTP header – `X-Slapdash-Hooks`. For example, in NodeJS this can look like: 58 | 59 | ```javascript 60 | async function myCommand(req, res) { 61 | // Your command logic is here. 62 | res.setHeader("Access-Control-Expose-Headers", "X-Slapdash-Hooks"); 63 | res.setHeader("X-Slapdash-Hooks", JSON.stringify({type: "url"})); 64 | } 65 | ``` 66 | 67 | Note, you also need to set `Access-Control-Expose-Headers` to the list of custom hooks that you want to expose. This ensures Slapdash can access `X-Slapdash-Hooks` when making a request to your endpoint. 68 | 69 | ### Local Commands 70 | 71 | To specify Hooks for Local Commands, you can use code comments in the following format: 72 | 73 | {% code title="command.js" %} 74 | ```javascript 75 | // @slapdash.hooks '{"type":"url"}' 76 | 77 | // You command logic is here. 78 | ``` 79 | {% endcode %} 80 | -------------------------------------------------------------------------------- /docs/command-bar-101/how-it-works.md: -------------------------------------------------------------------------------- 1 | # How it Works 2 | 3 | The Command Bar is a keyboard-centric interface for controlling your computer and cloud apps; with an emphasis on agency, speed and usability. The name is a combination of _command_ line and search _bar_. 4 | 5 | Like a command-line shell (i.e. bash, zsh), you can type your way to perform any task. Similarly, it’s also customizable and programmable. 6 | 7 | At the same time, it's as easy to use as a search bar. You don't need to learn anything: just type what you want in the Command Bar as you would in Google. 8 | 9 | ## Opening the Command Bar 10 | 11 | If you've ever used Mac's Spotlight feature, opening the Command Bar will be very familiar. It can be open from any application with one keyboard shortcut (**`⌘ J`** is the default for Slapdash). The Command Bar will appear on top of the application you are in. Clicking anywhere outside of it or hitting Esc will hide the Command Bar. To bring it back, just press the shortcut again. 12 | 13 | ## Doing Something 14 | 15 | When the Command Bar is open, you interact with it by typing. As you type, the Command Bar will show you interactive options, narrowing them down as you type. 16 | 17 | Hit **`Enter`** or click on an option to do something. Hitting **`Enter`** on a search result will open it. Hitting **`Enter`** on a command will run it. 18 | 19 | More precisely, hitting **`Enter`** runs the Action associated with the selected option. Every option will always have an Action. 20 | 21 | ![The Command Bar has returned some commands and search results that match keywords.](../.gitbook/assets/screen_shot\_2021-05-25\_at\_10.19.37\_pm.png) 22 | 23 | ## Moving Somewhere 24 | 25 | If you can open the Command Bar, type something and hit **`Enter`**, that's all you really need to know. 26 | 27 | However, there is one more important dimension to the Command Bar: _location_. 28 | 29 | Like a web page, the Command Bar has an address it's open to. And you can move to a different location by hitting **`Tab`**. It allows you to continue the experience in the Command Bar: like clicking a link to a different part of the app. 30 | 31 | Hitting **`Tab`** on a search result will give you new options like **Copy URL** or **Add to Space**, for example. 32 | 33 | The Location is visualized with pill-like tokens in the input of the Command Bar. If this was a URL, the path equivalent to the screenshot below would be: `/search?filter=github` 34 | 35 | ![Here the Command Bar is open to the Search command, with a Github filter applied.](../.gitbook/assets/screen_shot\_2021-05-23\_at\_3.35.09\_pm.png) 36 | 37 | ## Putting it Together 38 | 39 | In the below demonstration, the Command Bar is opened and "show" is typed into the input. 40 | 41 | The Command Bar view displays **Show Calendar Schedule** as one of the available options and selects it as the best match. 42 | 43 | Hitting **`Enter`** moves the Command Bar to the **Show Calendar Schedule** command's location. Here, **`Tab`** would have gotten you to same place. 44 | 45 | With the movement, the Command Bar now shows a "Show Calendar Schedule" token, which means you are running the "Show Calendar Schedule" command. The command shows your upcoming meetings as options. 46 | 47 | Hitting **`Tab`** on an event (one of the options) moves to a new location in the Command Bar that shows event details. 48 | 49 | **`Shift+Tab`** reverses the movement and brings you back to the list of events. 50 | 51 | Hitting **`Enter`** on the event option runs the **Action**, which in this case is to open the Zoom app directly to the meeting video chat. 52 | 53 | ![](../.gitbook/assets/command-fux.gif) 54 | -------------------------------------------------------------------------------- /docs/command-bar-101/local-commands.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Commands that run scripts on your computer. 3 | --- 4 | 5 | # Local Commands 6 | 7 | Local commands are just scripts that run on your computer. Slapdash knows how to run scripts in the most popular languages. 8 | 9 | Even if Slapdash doesn't support your language out of the box, you can just [use shebang syntax](../../templates/custom-shebang-not-bash.sh#L1), or create a bash wrapper to call into your program. 10 | 11 | ## Create Local Command 12 | 13 | To create a local command, run **Create New Command** in the Command Bar, choose **Local Script** as a type, select the script file on your computer, give your command a name and press **Create Command**. 14 | 15 | ![](../.gitbook/assets/cleanshot-2021-08-20-at-16.27.46.png) 16 | 17 | ## Language Support 18 | 19 | We try to support as many languages as possible. Below you'll find a list of languages you can use to build Slapdash commands. 20 | 21 | In practice, you can use a shebang directive to point to an interpreter of your choice. 22 | 23 | * AppleScript 24 | * bash / zsh 25 | * JavaScript 26 | * Perl 27 | * PowerShell 28 | * Python 29 | * Ruby 30 | * PHP 31 | * TypeScript 32 | 33 | ### AppleScript 34 | 35 | Support for AppleScript is baked into macOS. Just create a `command.applescript` file anywhere and start experimenting! 36 | 37 | Here's an example of an AppleScript command which [toggles the Mac OS system dark mode](../command-tutorials/toggle-dark-mode.md). 38 | 39 | ```applescript 40 | #!/usr/bin/osascript 41 | 42 | tell application "System Events" 43 | tell appearance preferences 44 | set dark mode to not dark mode 45 | end tell 46 | end tell 47 | ``` 48 | 49 | ### JavaScript 50 | 51 | Slapdash runs JavaScript commands using [Node](https://nodejs.org). 52 | 53 | Here is an example of a JavaScript command that displays a list with two options: 54 | 55 | ```javascript 56 | // command.js 57 | 58 | const response = { 59 | view: { 60 | type: "list", 61 | options: [ 62 | { 63 | title: "Open Slapdash", 64 | action: { 65 | type: "open-url", 66 | url: "https://slapdash.com" 67 | } 68 | }, 69 | { 70 | title: "Copy Heart Emoji", 71 | action: { 72 | type: "copy", 73 | value: "❤️" 74 | } 75 | } 76 | ] 77 | } 78 | }; 79 | 80 | console.log(JSON.stringify(response)); 81 | ``` 82 | 83 | When you run the command in the Command Bar, Slapdash will execute the underlying script: 84 | 85 | ```bash 86 | node command.js 87 | ``` 88 | 89 | ### TypeScript 90 | 91 | Slapdash runs TypeScript commands using [NodeJS](https://nodejs.org) and [ts-node](https://www.npmjs.com/package/ts-node). 92 | 93 | If you are building a command inside some package, Slapdash will also look inside its `node_modules` for the `ts-node` executable. If it can't find `ts-node` there it will look for `ts-node` in the global node modules location on your computer. 94 | 95 | ```typescript 96 | // command.ts 97 | 98 | // Optionally, import our npm package to get TS types for Command Response. 99 | import { CommandResponse } from "@slapdash/command-response-types"; 100 | 101 | const response: CommandResponse = { 102 | view: { 103 | type: "list", 104 | options: [ 105 | { 106 | title: "Open Slapdash", 107 | action: { 108 | type: "open-url", 109 | url: "https://slapdash.com", 110 | }, 111 | }, 112 | { 113 | title: "Copy Heart Emoji", 114 | action: { 115 | type: "copy", 116 | value: "❤️", 117 | }, 118 | }, 119 | ], 120 | }, 121 | }; 122 | 123 | console.log(JSON.stringify(response)); 124 | ``` 125 | 126 | When you run the command in the Command Bar, Slapdash will execute the underlying script: 127 | 128 | ```bash 129 | ts-node command.ts 130 | ``` 131 | 132 | ### Bash 133 | 134 | You already have [bash](https://en.wikipedia.org/wiki/Bash\_\(Unix\_shell\)) (or [zsh](https://en.wikipedia.org/wiki/Z\_shell)) on your Mac. No need to install anything. Just create e.g. `command.sh` file anywhere and start bashing: 135 | 136 | ```bash 137 | #!/bin/bash 138 | 139 | echo '{ 140 | "view": { 141 | "type": "list", 142 | "options": [ 143 | { 144 | "title": "Open Slapdash", 145 | "action": { 146 | "type": "open-url", 147 | "url": "https://slapdash.com" 148 | } 149 | }, 150 | { 151 | "title": "Copy Heart Emoji", 152 | "action": { 153 | "type": "copy", 154 | "value": "❤️" 155 | } 156 | } 157 | ] 158 | } 159 | }' 160 | ``` 161 | 162 | ### Python 163 | 164 | macOS has both Python v2 and Python v3 pre-installed, so you can just use it by default. Put the following to e.g. `command.py`: 165 | 166 | ```python 167 | #!python3 168 | # -*- coding: utf-8 -*- 169 | import json 170 | 171 | print(json.dumps({ 172 | "view": { 173 | "type": "list", 174 | "options": [ 175 | { 176 | "title": "Open Slapdash", 177 | "action": { 178 | "type": "open-url", 179 | "url": "https://slapdash.com" 180 | } 181 | }, 182 | { 183 | "title": "Copy Heart Emoji", 184 | "action": { 185 | "type": "copy", 186 | "value": "❤️" 187 | } 188 | } 189 | ] 190 | } 191 | })) 192 | ``` 193 | 194 | You can use Python v2 too: just change the [shebang line](https://en.wikipedia.org/wiki/Shebang\_\(Unix\)) to `#!python2` as usual. 195 | 196 | ### Ruby 197 | 198 | macOS should have Ruby pre-installed (or you can install it with `brew install ruby`). Put the following to e.g. `command.rb`: 199 | 200 | ```ruby 201 | #!/usr/bin/env ruby 202 | require 'json' 203 | 204 | print JSON.generate({ 205 | "view": { 206 | "type": "list", 207 | "options": [ 208 | { 209 | "title": "Open Slapdash", 210 | "action": { 211 | "type": "open-url", 212 | "url": "https://slapdash.com" 213 | } 214 | }, 215 | { 216 | "title": "Copy Heart Emoji", 217 | "action": { 218 | "type": "copy", 219 | "value": "❤️" 220 | } 221 | } 222 | ] 223 | } 224 | }) 225 | ``` 226 | 227 | ### Perl 228 | 229 | Perl is conveniently pre-installed on macOS. If you still remember how to write in Perl put the following to `command.pl`: 230 | 231 | ```perl 232 | #!/usr/bin/perl -w 233 | use utf8; 234 | use JSON; 235 | 236 | print encode_json({ 237 | "view" => { 238 | "type" => "list", 239 | "options" => [ 240 | { 241 | "title" => "Open Slapdash", 242 | "action" => { 243 | "type" => "open-url", 244 | "url" => "https://slapdash.com" 245 | } 246 | }, 247 | { 248 | "title" => "Copy Heart Emoji", 249 | "action" => { 250 | "type" => "copy", 251 | "value" => "❤️" 252 | } 253 | } 254 | ] 255 | } 256 | }) 257 | ``` 258 | 259 | ### PHP 260 | 261 | Some version of PHP is pre-installed on macOS, so it should work out of the box. Put the following to e.g. `command.php`: 262 | 263 | ```php 264 | #!php 265 | [ 268 | "type" => "list", 269 | "options" => [ 270 | [ 271 | "title" => "Open Slapdash", 272 | "action" => [ 273 | "type" => "open-url", 274 | "url" => "https://slapdash.com" 275 | ] 276 | ], 277 | [ 278 | "title" => "Copy Heart Emoji", 279 | "action" => [ 280 | "type" => "paste", 281 | "value" => "❤️" 282 | ] 283 | ] 284 | ] 285 | ] 286 | ]); 287 | ``` 288 | 289 | ### PowerShell 290 | 291 | [PowerShell](https://en.wikipedia.org/wiki/PowerShell) is already pre-installed on Windows. Just create a file with a `.ps1` extension. Here's an example that will empty your recycling bin. 292 | 293 | ``` 294 | Clear-RecycleBin -Force 295 | ``` 296 | 297 | ## Locating Language Binaries 298 | 299 | When searching for a programming language binary to execute the command script, we use the following approach: 300 | 301 | 1. We check the first line of the script, the same way it's done in Unix-like systems by looking for the shebang directive. If the first line looks like `#!/path/to/binary` or just `#!binary`, Slapdash calls the referenced interpreter to execute the command. 302 | 2. If there is no shebang directive, Slapdash will try to infer the language binary from the file's extension. For example, if it's a `*.rb` file, Slapdash will look for the installed Ruby binary. 303 | 3. If the script is within an npm package (JavaScript/TypeScript), Slapdash will check the current directory's `node_modules/.bin` folder to look for tools like `ts-node`. 304 | 4. Finally, Slapdash will use the OS's `PATH` environment variable to resolve the binary. 305 | -------------------------------------------------------------------------------- /docs/command-bar-101/publish-command.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Share your command with the Slapdash community 3 | --- 4 | 5 | # Publish Command 6 | 7 | Once you're happy with your command you may want to share it with others. 8 | 9 | A published command will appear as a "Community Command" on the [Slapdash developer site](https://slapdash.com/developers), allowing anyone to discover it and add it to their Slapdash account. 10 | 11 | ## Publish Cloud Command 12 | 13 | To publish a command, you need to fork the [slapdash/platform](https://github.com/slapdash/platform) repository, create a new folder inside [commands](https://github.com/slapdash/platform/tree/main/commands) and then open a Pull Request. Once your PR is merged, your command will appear on the Slapdash site, allowing anyone to install it.\ 14 | \ 15 | Each command gets its own folder and needs to follow some simple conventions. Here's an example of how a new command might be added to the repository. 16 | 17 | Please name your command folder using the [kebab case style](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles) (lowercase and hyphen used as a separator). 18 | 19 | ``` 20 | commands 21 | └── my-command-name 22 | ├── command.toml 23 | ├── icon.svg 24 | └── screenshot.json 25 | ``` 26 | 27 | Each command folder needs to have three files: `command.toml`, `icon.svg `and `screenshot.json`. You can copy other commands as examples, or read about the role of each file below. 28 | 29 | #### `command.toml` 30 | 31 | This is a simple [TOML](https://toml.io) file that contains metadata about your command. 32 | 33 | | Name | Details | 34 | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | 35 | | name | **Required.** Name of the command, prefer \ \ convention | 36 | | description | **Required**. Short, one-sentence description | 37 | | endpointURL | **Required**. Publicly accessible HTTPS endpoint for your command | 38 | | author.name | **Required**. Full name of the command's author | 39 | | author.profileURL | **Required**. Link to the author's public profile. For example, a link to a Github or Twitter profile. | 40 | | categories | List of categories the command belongs to. You can grab them from the [list below](publish-command.md#categories) or put something else. | 41 | | readme | Long-form explanation of the command. You can use Markdown if you want. | 42 | | language | Language that was used to build the command. For example, "TypeScript" or "Python". | 43 | | sourceCodeURL | Link to the source code of your command. For example, a link to a public Github repository. | 44 | 45 | #### `icon.svg` or `icon.monochrome.svg` 46 | 47 | This is the icon that will be used alongside your command, when it appears in the Command bar. If you want Slapdash to automatically change the icon's color based on the selected theme, use `icon.monochrome.svg`. 48 | 49 | We recommend a 64x64 px icon with no padding around it. If you need help finding an icon, you can try using the [Search Iconfinder](https://slapdash.com/commands/search-iconfinder) command. 50 | 51 | #### `screenshot.json` 52 | 53 | This file is added by Slapdash employees so you don't need to provide it. It is a simple JSON file that contains one of the [Command Responses](../reference/command-response.md) that your command returned as well as some other metadata to help visualize the command on the Slapdash site. 54 | 55 | ## Publish Local Command 56 | 57 | There is currently no way to publish a Local Command but we're actively working on it. It should be available very soon. Stay tuned! 58 | 59 | ## Categories 60 | 61 | If you're not sure what category to put your command in, don't sweat it, we'll help categorize it. Here are some potential categories you might want to consider (or, just make up your own). 62 | 63 | * Automation 64 | * Books 65 | * Business 66 | * Developer Tools 67 | * Education 68 | * Entertainment 69 | * Finance 70 | * Food & Drink 71 | * Games 72 | * Health & Fitness 73 | * Design 74 | * Lifestyle 75 | * Kids 76 | * Magazines & Newspapers 77 | * Medical 78 | * Music 79 | * Navigation 80 | * News 81 | * Photo & Video 82 | * Productivity 83 | * Shopping 84 | * Social Networking 85 | * Sports 86 | * Travel 87 | * Utilities 88 | -------------------------------------------------------------------------------- /docs/command-bar-101/setup-your-first-command.md: -------------------------------------------------------------------------------- 1 | # Build Your First Command 2 | 3 | Slapdash works great in the browser, but for the best development experience, we recommend using the [Slapdash desktop app](https://slapdash.com/download). 4 | 5 | There are [two types of commands](commands.md#local-vs-cloud-commands): **Local Commands**, which are scripts that run on your computer, and **Cloud Commands**, which are commands that are hosted on the web. Developing is easier and faster with files on your computer, so that's the type of command we'll be writing here. 6 | 7 | This example command will be written in JavaScript, but in practice, you can use [whatever language](local-commands.md#language-support) you are comfortable with. 8 | 9 | ### Create Command 10 | 11 | * Create an empty file with a `.js` extension (for example: `ahoy-world.js`) 12 | * Run **Create New Command** in the Command Bar and choose **Local Script** 13 | * Choose the file you created by clicking the **Select File **button**.** 14 | * Give the command a name, for example, "Run Demo" 15 | 16 | ### Do Something with the Command 17 | 18 | For the Command to do something or show something in the Command Bar, it just needs to print some text. Specifically, the text needs to be JSON that matches the shape of the [Command Response Specification](../reference/command-response.md). 19 | 20 | The most basic thing a command can do is return an Action as the [Command Response](../reference/command-response.md). An Action just tells the Command Bar to do some operation and exit. The simplest one is to just open a URL. 21 | 22 | #### **Make Your Command Open a URL** 23 | 24 | ```javascript 25 | const response = { 26 | action: { 27 | type: "open-url", 28 | url: "https://slapdash.com/" 29 | } 30 | } 31 | 32 | // Print the response as JSON string 33 | console.log(JSON.stringify(response)); 34 | ``` 35 | 36 | Another type of Action is to add something to your clipboard. You can see other Actions in the [Command Response Reference](../reference/command-response-action.md). 37 | 38 | #### **Make Your Command Add Some Text to Your Clipboard** 39 | 40 | ```javascript 41 | const response = { 42 | action: { 43 | type: "copy", 44 | value: "Ahoy world!" 45 | } 46 | } 47 | 48 | // Print the response as JSON string 49 | console.log(JSON.stringify(response)); 50 | ``` 51 | -------------------------------------------------------------------------------- /docs/command-tutorials/copy-special-character.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: 'Find a special character, then copy the character or its hex value' 3 | --- 4 | 5 | # Copy Special Character 6 | 7 | ![](../.gitbook/assets/copy-special-character.gif) 8 | 9 | This command illustrates an [interactive List](../reference/command-response-view-list.md), as well as using **Tab** to navigate to another location within the command. 10 | 11 | In this case, hitting **Enter** on an Option will copy the special character, while hitting **Tab** will show another view letting someone choose to copy the hex value instead. 12 | 13 | ```javascript 14 | /* 15 | * A command that shows special characters. Hitting Enter 16 | * will copy character, hitting Tab will give other ways 17 | * to copy the character: HTML hex code, for example. 18 | */ 19 | 20 | /** 21 | * Gets arguments passed in to script, like: --character=control 22 | * and stores it into an array, like: args['character'] = "control". 23 | */ 24 | const args = process.argv.slice(2).reduce((agg, arg) => { 25 | const match = arg.match(/^--(?\w+)=(?.+)$/); 26 | return match ? { ...agg, [match.groups.key]: match.groups.value } : agg; 27 | }, {}); 28 | 29 | let response; 30 | if (args["character"]) { 31 | response = showOptionsForCharacter(args["character"]); 32 | } else { 33 | response = showAllCharacters(); 34 | } 35 | console.log(JSON.stringify(response)); 36 | 37 | /* 38 | * The view that is shown when someone runs the command. 39 | */ 40 | function showAllCharacters() { 41 | const response = { 42 | view: { 43 | type: "list", 44 | options: [ 45 | { 46 | title: "Command", 47 | action: { 48 | type: "copy", 49 | value: "⌘", 50 | }, 51 | moveAction: { 52 | type: "add-param", 53 | name: "character", 54 | value: "command", 55 | }, 56 | }, 57 | { 58 | title: "Option", 59 | action: { 60 | type: "copy", 61 | value: "⌥", 62 | }, 63 | moveAction: { 64 | type: "add-param", 65 | name: "character", 66 | value: "option", 67 | }, 68 | }, 69 | { 70 | title: "Control", 71 | action: { 72 | type: "copy", 73 | value: "️️⌃", 74 | }, 75 | moveAction: { 76 | type: "add-param", 77 | name: "character", 78 | value: "control", 79 | }, 80 | }, 81 | ], 82 | }, 83 | }; 84 | return response; 85 | } 86 | 87 | /** 88 | * The view that is shown when someone Tabs on a character. 89 | */ 90 | function showOptionsForCharacter(character) { 91 | const charactersToHex = { 92 | command: "⌘", 93 | option: "⌥", 94 | control: "⌃", 95 | }; 96 | return { 97 | tokens: [ 98 | { 99 | paramName: "character", 100 | label: character, 101 | icon: "🎹", 102 | }, 103 | ], 104 | view: { 105 | type: "list", 106 | options: [ 107 | { 108 | title: "Copy Hex", 109 | action: { 110 | type: "copy", 111 | value: charactersToHex[character], 112 | }, 113 | }, 114 | ], 115 | }, 116 | }; 117 | } 118 | ``` 119 | 120 | [See on Github](https://github.com/slapdash/platform/tree/main/tutorials/copy-special-character) 121 | 122 | -------------------------------------------------------------------------------- /docs/command-tutorials/emoji-paster.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Search & paste emojis 3 | --- 4 | 5 | # Emoji Paster 6 | 7 | ![](../.gitbook/assets/emoji-paster.gif) 8 | 9 | This command illustrates how to return an interactive [List view](../reference/command-response-view-list.md). In this case, we visualize emojis and their names. As you type, the command matches the emoji name. When you hit **Enter**, the command pastes the selected emoji in the active app. 10 | 11 | In this example, you'll also notice that you can use an emoji as a custom icon for an [Option](../reference/command-response-view-list.md#listoption). 12 | 13 | ```javascript 14 | /** 15 | * A command that shows a selection of emojis and pastes 16 | * the selected emoji on pressing Enter. 17 | */ 18 | const response = { 19 | view: { 20 | type: "list", 21 | options: [ 22 | { 23 | title: "Heart", 24 | action: { 25 | type: "paste", 26 | value: "❤️", 27 | }, 28 | icon: "❤️", 29 | }, 30 | { 31 | title: "Star", 32 | action: { 33 | type: "paste", 34 | value: "⭐️", 35 | }, 36 | icon: "⭐️", 37 | }, 38 | { 39 | title: "Lightning", 40 | action: { 41 | type: "paste", 42 | value: "️⚡️", 43 | }, 44 | icon: "⚡️", 45 | }, 46 | ], 47 | }, 48 | }; 49 | 50 | console.log(JSON.stringify(response)); 51 | ``` 52 | 53 | [See on Github](https://github.com/slapdash/platform/tree/main/tutorials/emoji-paster) 54 | 55 | -------------------------------------------------------------------------------- /docs/command-tutorials/send-slack-message.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Show list of Slack users and quickly jump to DM thread 3 | --- 4 | 5 | # Send Slack Message 6 | 7 | ![](../.gitbook/assets/send-slack-message.gif) 8 | 9 | Some commands may require some configuration, which you might not want to add to your command source code. For example, you might need an API key. 10 | 11 | Slapdash provides an interface for your command to collect configuration data, which is then sent alongside each command run. 12 | 13 | The first time you run the command, it asks for the Slack Bot authentication token, then shows the list of users in Slack. If a user is selected, the Slack desktop is opened directly to the DM thread of the selected user. 14 | 15 | ![The command asks to provide the Slack Bot Token.](../.gitbook/assets/image%20%282%29.png) 16 | 17 | This is an example of a [Cloud Command](../command-bar-101/cloud-commands.md), a command that runs on a server. 18 | 19 | With a Cloud Command, you can share its URL with anyone, and each person will be able to use the command with their own authentication tokens. 20 | 21 | {% hint style="info" %} 22 | See [Cloud Commands](https://developers.slapdash.com/command-bar-101/cloud-commands) for details on how to create and deploy cloud commands. 23 | {% endhint %} 24 | 25 | ```python 26 | #!python 27 | # -*- coding: utf-8 -*- 28 | from flask import Flask, jsonify, request 29 | from requests import get 30 | 31 | MIN_TOKEN_LEN = 10 32 | HELP_TEXT = """ 33 | To obtain the token,\n 34 | - Create a Slack App at [Slack Apps page](https://api.slack.com/apps) (from scratch); 35 | - Click **Bots**, then **Review Scopes to Add**; 36 | - Add **users:read** Bot Token scope and then click **Install to Workspace** above; 37 | - Copy bot token and paste in this field. 38 | """ 39 | 40 | app = Flask(__name__) 41 | 42 | def get_name(member): 43 | return member["profile"]["real_name"] or member["profile"]["display_name"] 44 | 45 | @app.route("/", methods=["GET", "POST"]) 46 | def command(): 47 | # Read config field. If it's not yet entered by the user, show them the input 48 | # form. Slapdash will save the entered value and not re-request again. 49 | token = request.headers.get("slack-token") 50 | if not token or len(token) < MIN_TOKEN_LEN: 51 | return jsonify({ 52 | "config": { 53 | "form": { 54 | "fields": [ 55 | { 56 | "type": "text", 57 | "id": "slack-token", 58 | "label": "Slack Bot Token", 59 | "placeholder": "xoxb-***-***-***", 60 | "helpText": HELP_TEXT, 61 | "defaultValue": token, 62 | "error": "Invalid token" if token and len(token) < MIN_TOKEN_LEN else None 63 | } 64 | ] 65 | } 66 | } 67 | }) 68 | 69 | # We have the token. Send Slack API request. 70 | res = get( 71 | url="https://slack.com/api/users.list?pretty=1", 72 | headers={"Authorization": "Bearer " + token} 73 | ) 74 | 75 | # Build CommandResponse from the Slack response. 76 | return jsonify({ 77 | "view": { 78 | "type": "list", 79 | "options": [ 80 | { 81 | "title": "@" + member["name"] + 82 | (" — " + get_name(member) if get_name(member) else ""), 83 | "icon": member["profile"]["image_48"], 84 | "action": { 85 | "type": "open-url", 86 | "url": "slack://user?team=%s&id=%s" % (member["team_id"], member["id"]) 87 | } 88 | } 89 | for member in res.json()["members"] 90 | if not member["is_bot"] and not member["deleted"] 91 | ] 92 | } 93 | }) 94 | 95 | @app.after_request 96 | def add_header(response): 97 | response.headers["Access-Control-Allow-Headers"] = "*" # for config headers 98 | response.headers["Access-Control-Allow-Origin"] = "*" 99 | return response 100 | 101 | if __name__ == "__main__": 102 | app.run(host="0.0.0.0", port=8080, debug=True) 103 | ``` 104 | 105 | -------------------------------------------------------------------------------- /docs/command-tutorials/toggle-dark-mode.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: A Mac OS command that uses AppleScript 3 | --- 4 | 5 | # Toggle Dark Mode 6 | 7 | ![Run Toggle Dark Mode in Command Bar](<../.gitbook/assets/toggle-dark-mode (1) (2) (2) (2) (2) (2).gif>) 8 | 9 | This is an example that will only work on macOS because it uses AppleScript. It's an example of a command that doesn't return a response: it just does its thing and exits. 10 | 11 | When the command is run, it will toggle the dark mode system preference setting. 12 | 13 | Paste the following code in a new file with a `.applescript` extension and then [create a Local Command](../command-bar-101/local-commands.md#create-local-command) to try it out in Slapdash. 14 | 15 | ```javascript 16 | tell application "System Events" 17 | tell appearance preferences 18 | set dark mode to not dark mode 19 | end tell 20 | end tell 21 | ``` 22 | 23 | [See on Github](https://github.com/slapdash/platform/tree/main/tutorials/toggle-dark-mode) 24 | -------------------------------------------------------------------------------- /docs/reference/command-response-action.md: -------------------------------------------------------------------------------- 1 | # Action 2 | 3 | Actions tell the Command Bar to perform a side effect (e.g. open a URL or copy something to the clipboard). They can be used in two places: 4 | 5 | * at the root of [Command Response](command-response.md) as `CommandResponse.action` 6 | * in the Option of the [List View](command-response-view-list.md) or [Masonry View](command-response-view-masonry.md) as `CommandResponse.view.options[].action` 7 | 8 | ```typescript 9 | export type Action = 10 | | ActionOpenURL 11 | | ActionPaste 12 | | ActionCopy 13 | | ActionShowToast 14 | | ActionMove; 15 | 16 | type ActionMove = ActionMoveAddParam; 17 | ``` 18 | 19 | ## ActionOpenURL 20 | 21 | Opens a given URL using the system's default handler. 22 | 23 | * **type:** `"open-url"` 24 | * **url:** The URL to open. You can use any valid URI schema. For example, "https://", "file://", "ssh://", "slack://" (native app). Provide a string to open a single URL or an array of strings to open multiple URLs at once. 25 | 26 | {% tabs %} 27 | {% tab title="Open a URL in the browser" %} 28 | ```javascript 29 | { 30 | "action": { 31 | "type": "open-url", 32 | "url": "https://slapdash.com/", 33 | } 34 | } 35 | ``` 36 | {% endtab %} 37 | 38 | {% tab title="Open multiple URLs at once" %} 39 | ``` 40 | { 41 | "action": { 42 | "type": "open-url", 43 | "url": [ 44 | "https://google.com/", 45 | "https://bing.com/" 46 | ] 47 | } 48 | } 49 | ``` 50 | {% endtab %} 51 | 52 | {% tab title="List View: open Google and Bing URLs" %} 53 | ```typescript 54 | { 55 | "view": { 56 | "type": "list", 57 | "options": [ 58 | { 59 | "title": "Open Google", 60 | "action": { 61 | "type": "open-url", 62 | "url": "https://www.google.com/" 63 | } 64 | }, 65 | { 66 | "title": "Open Bing", 67 | "action": { 68 | "type": "open-url", 69 | "url": "https://www.bing.com/" 70 | } 71 | } 72 | ] 73 | } 74 | } 75 | ``` 76 | {% endtab %} 77 | 78 | {% tab title="Open a local folder in Finder" %} 79 | ```typescript 80 | { 81 | "action": { 82 | "type": "open-url", 83 | "url": "file:///Users/Johny/Downloads", 84 | } 85 | } 86 | ``` 87 | {% endtab %} 88 | 89 | {% tab title="Open a Slack channel in the Slack desktop app" %} 90 | ```typescript 91 | { 92 | "action": { 93 | "type": "open-url", 94 | "url": "slack://channel?team=TA4PV0NH4&id=CR7EDED9Q" 95 | } 96 | } 97 | ``` 98 | {% endtab %} 99 | {% endtabs %} 100 | 101 | ## ActionPaste 102 | 103 | Pastes some text to the active app. 104 | 105 | * **type:** `"paste"` 106 | * **value:** The string that will be pasted to the active app. 107 | 108 | {% tabs %} 109 | {% tab title="Paste text to the active app" %} 110 | ```typescript 111 | { 112 | "action": { 113 | "type": "paste", 114 | "value": "Hello, world!" 115 | } 116 | } 117 | ``` 118 | {% endtab %} 119 | 120 | {% tab title="List View: paste an email address to the active app" %} 121 | ```typescript 122 | { 123 | "view": { 124 | "type": "list", 125 | "options": [ 126 | { 127 | "title": "Paste My Email", 128 | "action": { 129 | "type": "paste", 130 | "value": "my-personal-email@gmail.com" 131 | } 132 | } 133 | ] 134 | } 135 | } 136 | ``` 137 | {% endtab %} 138 | {% endtabs %} 139 | 140 | ## ActionCopy 141 | 142 | Copies some text to the clipboard. 143 | 144 | * **type:** `"copy"` 145 | * **value:** The string that will be copied to the clipboard. 146 | 147 | {% tabs %} 148 | {% tab title="Copy text to clipboard" %} 149 | ```typescript 150 | { 151 | "action": { 152 | "type": "copy", 153 | "value": "Hello, world!" 154 | } 155 | } 156 | ``` 157 | {% endtab %} 158 | 159 | {% tab title="List View: option to copy a URL to clipboard" %} 160 | ```typescript 161 | { 162 | "view": { 163 | "type": "list", 164 | "options": [ 165 | { 166 | "title": "Copy Google URL", 167 | "action": { 168 | "type": "copy", 169 | "value": "https://www.google.com/" 170 | } 171 | } 172 | ] 173 | } 174 | } 175 | ``` 176 | {% endtab %} 177 | {% endtabs %} 178 | 179 | ## ActionShowToast 180 | 181 | Shows a message in a toast (an ephemeral message displayed on the screen). 182 | 183 | * **type:** `"show-toast"` 184 | * **message:** The message that will be displayed in a toast. 185 | 186 | {% tabs %} 187 | {% tab title="Show a confirmation message in a toast" %} 188 | ```typescript 189 | { 190 | "view": { 191 | "type": "list", 192 | "options": [ 193 | { 194 | "title": "Show a Message", 195 | "action": { 196 | "type": "show-toast", 197 | "message": "The task has been successfully completed!" 198 | } 199 | } 200 | ] 201 | } 202 | } 203 | ``` 204 | {% endtab %} 205 | {% endtabs %} 206 | 207 | ## ActionMoveAddParam 208 | 209 | Allows to change the [location of the Command Bar](../command-bar-101/core-terminology.md#location). Currently, there is only one Move Action supported – add a param. Location parameters are then passed to the Command when it's run. 210 | 211 | Typically, the "add-param" Action is used in the `moveAction` property of some [Option](command-response-view-list.md#listoption) that can be triggered by pressing **`Tab`**. 212 | 213 | * **type:** `"add-param"` 214 | * **name:** The name of the parameter. 215 | * **value:** The value of the parameter. 216 | 217 | {% tabs %} 218 | {% tab title="Masonry View: option with Main and Move Actions" %} 219 | ```typescript 220 | { 221 | "view": { 222 | "type": "masonry", 223 | "options": [ 224 | { 225 | "imageURL": "https://images.unsplash.com/photo-1481819613568-3701cbc70156", 226 | "action": { 227 | "type": "open-url", 228 | "url": "https://images.unsplash.com/photo-1481819613568-3701cbc70156" 229 | }, 230 | "moveAction": { 231 | "type": "add-param", 232 | "name": "image", 233 | "value": "moon" 234 | } 235 | } 236 | ] 237 | } 238 | } 239 | ``` 240 | {% endtab %} 241 | {% endtabs %} 242 | -------------------------------------------------------------------------------- /docs/reference/command-response-config.md: -------------------------------------------------------------------------------- 1 | # Config 2 | 3 | Config allows displaying a "one-time" form in the Command Bar. All values from this form will be securely stored on the server and sent to the command any time it is run. Useful when a command requires some configuration (e.g. API key) before it can be run. 4 | 5 | To see a real example, check out the [Send Slack Message](../command-tutorials/send-slack-message.md) command. 6 | 7 | ## Config 8 | 9 | {% tabs %} 10 | {% tab title="Simple Config Form" %} 11 | ```json 12 | { 13 | "config": { 14 | "form": { 15 | "fields": [ 16 | { 17 | "type": "text", 18 | "id": "api-key", 19 | "label": "API Key", 20 | "placeholder": "GIPHY API key" 21 | } 22 | ] 23 | } 24 | } 25 | } 26 | ``` 27 | {% endtab %} 28 | 29 | {% tab title="Config Form with Error" %} 30 | ```json 31 | { 32 | "config": { 33 | "form": { 34 | "error": "This API Key has expired", 35 | "fields": [ 36 | { 37 | "type": "text", 38 | "id": "api-key", 39 | "label": "API Key", 40 | "placeholder": "GIPHY API key" 41 | } 42 | ] 43 | } 44 | } 45 | } 46 | ``` 47 | {% endtab %} 48 | {% endtabs %} 49 | 50 | ## Show Config Conditionally 51 | 52 | You will likely want to show the configuration form to the user conditionally, e.g. when the user hasn't entered the values yet or when the values are incorrect. See the [Send Slack Message](../command-tutorials/send-slack-message.md) on how to do it. 53 | -------------------------------------------------------------------------------- /docs/reference/command-response-icon.md: -------------------------------------------------------------------------------- 1 | # Icon 2 | 3 | The icon can be provided in different ways to help you fine-tune its appearance. 4 | 5 | ```typescript 6 | type Icon = 7 | | string 8 | | { 9 | light: string; 10 | dark: string; 11 | } 12 | | { 13 | monochrome: string; 14 | }; 15 | ``` 16 | 17 | Slapdash supports loading icons over `http://` , `https://`, using[ Data URLs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) or providing the raw icon content inline. 18 | 19 | ```typescript 20 | // Emoji can be provided inline. All Unicode Emoticons are supported. 21 | icon: "🧛‍♂️" 22 | 23 | // Icons accessible over HTTP/HTTPS can be provided as an absolute URL. 24 | icon: "https://slapdash.com/favicon.ico" 25 | 26 | // SVGs can be provided inline. 27 | icon: '' 28 | 29 | // Icons can be encoded as Data URLs and provided inline. The following 30 | // formats are supported: image/png, image/jpeg, image/gif, image/svg+xml. 31 | icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAKBJREFUeNpiYBjpgBFd4P///wJAaj0QO9DEQiAg5ID9tLIcmwMYsDgABhqoaTHMUHRxpsGYBv5TGqTIZsDkYWLo6gc8BEYdMOqAUQeMOoAqDgAWcgZAfB9EU63SIAGALH8PZb+H8v+jVz64KiOK6wIg+ADEArj4hOoCajiAqMpqtDIadcCoA0YdQIoDDtCqQ4KtBY3NAYG0csQowAYAAgwAgSqbls5coPEAAAAASUVORK5CYII=" 32 | ``` 33 | 34 | ### Customize 35 | 36 | By default, Slapdash will display icons "as is" but you can choose to render different icons depending on the selected theme: 37 | 38 | ```typescript 39 | icon: { 40 | light: "🌞", 41 | dark: "🌔" 42 | } 43 | ``` 44 | 45 | Or, you can tell Slapdash to automatically adjust the icon color based on the current theme: 46 | 47 | ```typescript 48 | icon: { 49 | monochrome: "https://example.com/icon.svg" 50 | } 51 | ``` 52 | 53 | In this case, Slapdash will replace all non-transparent pixels of the icon with the appropriate color from the selected theme. 54 | 55 | -------------------------------------------------------------------------------- /docs/reference/command-response-tokens.md: -------------------------------------------------------------------------------- 1 | # Tokens 2 | 3 | Tokens allow customizing how the command's parameters are displayed in the input of the Command Bar. 4 | 5 | * **paramName:** The name of the parameter associated with this token. These parameters are typically added with [ActionMoveAddParam](command-response-action.md#actionmoveaddparam). 6 | * **label:** Optional. The label for the token. By default, the parameter's name is used. 7 | * **icon:** Optional. The [Icon](command-response-icon.md) for the token. 8 | 9 | {% tabs %} 10 | {% tab title="Masonry View: custom label and icon for a token" %} 11 | ```javascript 12 | { 13 | "tokens": [ 14 | { 15 | "paramName": "image", 16 | "label": "Moon", 17 | "icon": "🌜" 18 | } 19 | ], 20 | "view": { 21 | "type": "masonry", 22 | "options": [ 23 | { 24 | "imageURL": "https://images.unsplash.com/photo-1481819613568-3701cbc70156", 25 | "action": { 26 | "type": "open-url", 27 | "url": "https://images.unsplash.com/photo-1481819613568-3701cbc70156" 28 | }, 29 | "moveAction": { 30 | "type": "add-param", 31 | "name": "image", 32 | "value": "moon" 33 | } 34 | } 35 | ] 36 | } 37 | } 38 | ``` 39 | {% endtab %} 40 | {% endtabs %} 41 | 42 | -------------------------------------------------------------------------------- /docs/reference/command-response-view-form.md: -------------------------------------------------------------------------------- 1 | # Form View 2 | 3 | Form View allows to request some data from the user. When the form is submitted, the command will receive all values in the respective parameters. 4 | 5 | The delivery method depends on the type of your command. For [Local Commands](../command-bar-101/local-commands.md), the form data is sent using stdin, and for [Cloud Commands](../command-bar-101/cloud-commands.md), it's sent using a GET or POST request. 6 | 7 | ## Form 8 | 9 | Property `CommandResponse.view` of type `Form` allows showing a custom form in the Command Bar. 10 | 11 | * **type:** `"form"` 12 | * **fields:** An array of [FormField](command-response-view-form.md#formfield) objects. By default, each field will be displayed in a separate row. If you want some fields to be displayed in the same row – put them in a nested array, the available space will be evenly split between them. See examples below for more details. 13 | * **title:** Optional. Title of the form. 14 | * **submitLabel:** Optional. Text label for the submit button. 15 | * **cancelLabel:** Optional. Text label for the cancel button. 16 | * **method:** Optional. `"get"` or `"post"` (default). HTTP request method that will be used to submit the form. This is only relevant to [Cloud Commands](../command-bar-101/cloud-commands.md). 17 | * **error**. Optional. The error message to show for the whole form. 18 | 19 | {% tabs %} 20 | {% tab title="Simple form to order a drink" %} 21 | ```javascript 22 | { 23 | "view": { 24 | "type": "form", 25 | "title": "Order Drink", 26 | "submitLabel": "Order", 27 | "fields": [ 28 | { 29 | "type": "text", 30 | "id": "name", 31 | "label": "Your Name" 32 | }, 33 | { 34 | "type": "select", 35 | "id": "drink", 36 | "label": "Drink", 37 | "options": [ 38 | "Cappuccino", 39 | "Latte", 40 | "Green Tea", 41 | "Coke" 42 | ] 43 | } 44 | ] 45 | } 46 | } 47 | ``` 48 | {% endtab %} 49 | 50 | {% tab title="Multiple fields on the same row" %} 51 | ```javascript 52 | { 53 | "view": { 54 | "type": "form", 55 | "fields": [ 56 | [ 57 | { 58 | "type": "text", 59 | "id": "firstName", 60 | "label": "First Name" 61 | }, 62 | { 63 | "type": "text", 64 | "id": "lastName", 65 | "label": "Last Name" 66 | }, 67 | { 68 | "type": "toggle", 69 | "id": "subscribe", 70 | "label": "Subscribe to Newsletter" 71 | } 72 | ], 73 | { 74 | "type": "textarea", 75 | "id": "notes", 76 | "label": "Notes" 77 | } 78 | ] 79 | } 80 | } 81 | ``` 82 | {% endtab %} 83 | {% endtabs %} 84 | 85 | ## FormField 86 | 87 | Property `CommandResponse.view.fields` defines an array of fields in the Form View. There are multiple different form field types that allow creating sophisticated forms. 88 | 89 | ```typescript 90 | type FormField = TextField | ToggleField | SelectField | DateField; 91 | ``` 92 | 93 | ### TextField 94 | 95 | A plain-text input, similar to the HTML `` tag, defines a field where a user can enter free-form data. 96 | 97 | * **type:** `"text"` 98 | * **id:** ID of the field. Must be unique in the Form view. 99 | * **label:** Label for the field. 100 | * **required:** Optional, `true` or `false`. Whether this field is required. 101 | * **defaultValue:** Optional. The initial text value for this field. 102 | * **error:** Optional. If set, shows an error message under the field. 103 | * **helpText:** Optional. A Markdown text which will be displayed under the field. 104 | * **placeholder:** Optional. Placeholder for this field, displayed inside the field in gray. 105 | * **multiline:** Optional, `true` or `false`. Whether the field should be displayed as a large textarea. 106 | 107 | {% tabs %} 108 | {% tab title="Single line text field" %} 109 | ```javascript 110 | { 111 | "view": { 112 | "type": "form", 113 | "fields": [ 114 | { 115 | "type": "text", 116 | "id": "name", 117 | "label": "Name", 118 | "required": true, 119 | "defaultValue": "Steve", 120 | "placeholder": "Tell us your name" 121 | } 122 | ] 123 | } 124 | } 125 | ``` 126 | {% endtab %} 127 | 128 | {% tab title="Large textarea field" %} 129 | ```typescript 130 | { 131 | "view": { 132 | "type": "form", 133 | "fields": [ 134 | { 135 | "type": "text", 136 | "id": "notes", 137 | "label": "Your Notes", 138 | "placeholder": "What is on your mind?", 139 | "multiline": true 140 | } 141 | ] 142 | } 143 | } 144 | ``` 145 | {% endtab %} 146 | {% endtabs %} 147 | 148 | ### ToggleField 149 | 150 | Defines a field that allows the user to enable or disable something. 151 | 152 | * **type:** `"toggle"` 153 | * **id:** ID of the field. Must be unique in the Form View. 154 | * **label:** Label for the field. 155 | * **required:** Optional, `true` or `false`. Whether this field is required. 156 | * **defaultValue:** Optional, `true` or `false`. The default value for this field. 157 | * **error:** Optional. If set, shows an error message under the field. 158 | * **helpText:** Optional. A Markdown text which will be displayed under the field. 159 | 160 | {% tabs %} 161 | {% tab title="Simple toggle field" %} 162 | ```typescript 163 | { 164 | "view": { 165 | "type": "form", 166 | "fields": [ 167 | { 168 | "type": "toggle", 169 | "id": "subscribe", 170 | "label": "Subscribe to Newsletter", 171 | "defaultValue": true 172 | } 173 | ] 174 | } 175 | } 176 | ``` 177 | {% endtab %} 178 | {% endtabs %} 179 | 180 | ### DateField 181 | 182 | Defines a field which lets the user easily select a date from a calendar style UI. 183 | 184 | * **type:** `"date"` 185 | * **id:** ID of the field. Must be unique in the Form View. 186 | * **label:** Label for the field. 187 | * **required:** Optional, `true` or `false`. Whether this field is required. 188 | * **defaultValue:** Optional. Default value for this field as a Date string. 189 | * **error:** Optional. If set, shows an error message under the field. 190 | * **helpText:** Optional. A Markdown text which will be displayed under the field. 191 | * **timeSelect:** Optional, `true` or `false` (default). Whether the field allows selecting the time too. 192 | 193 | {% tabs %} 194 | {% tab title="Simple date field" %} 195 | ```typescript 196 | { 197 | "view": { 198 | "type": "form", 199 | "title": "When is your birthday?", 200 | "fields": [ 201 | { 202 | "type": "date", 203 | "id": "dateOfBirth", 204 | "label": "Your Date of Birth" 205 | } 206 | ] 207 | } 208 | } 209 | ``` 210 | {% endtab %} 211 | {% endtabs %} 212 | 213 | ### SelectField 214 | 215 | Defines a field that allows the user to select one or multiple options. 216 | 217 | * **type:** `"select"` 218 | * **id:** ID of the field. Must be unique in the Form View. 219 | * **label:** Label for the field. 220 | * **options:** A list of strings or [SelectOption](command-response-view-form.md#selectoption) objects that a user can select from. 221 | * **required:** Optional, `true` or `false`. Whether this field is required. 222 | * **defaultValue:** Optional. Default value for this field. If the field allows selecting multiple values (see `multiple`), an array of strings can be provided. 223 | * **error:** Optional. If set, shows an error message under the field. 224 | * **helpText:** Optional. A Markdown text which will be displayed under the field. 225 | * **multiple:** Optional, `true` or `false`. Whether the field allow selecting single or multiple options. 226 | * **placeholder:** Optional. Placeholder of the field, shown inside in gray. 227 | 228 | #### SelectOption 229 | 230 | Allows to customize options for [SelectField](command-response-view-form.md#selectfield). 231 | 232 | * **label:** Label for the option. 233 | * **value:** Value of the option. 234 | 235 | {% tabs %} 236 | {% tab title="Select field that allows to pick only one option" %} 237 | ```typescript 238 | { 239 | "view": { 240 | "type": "form", 241 | "fields": [ 242 | { 243 | "type": "select", 244 | "id": "country", 245 | "label": "Country of Residence", 246 | "options": [ 247 | "Ukraine", 248 | "Spain", 249 | "Germany" 250 | ] 251 | } 252 | ] 253 | } 254 | } 255 | ``` 256 | {% endtab %} 257 | 258 | {% tab title="Select field with custom options" %} 259 | ```typescript 260 | { 261 | "view": { 262 | "type": "form", 263 | "fields": [ 264 | { 265 | "type": "select", 266 | "id": "country", 267 | "label": "Country of Residence", 268 | "options": [ 269 | { 270 | "value": "ukr", 271 | "label": "Ukraine" 272 | }, 273 | { 274 | "value": "s", 275 | "label": "Spain" 276 | }, 277 | { 278 | "value": "g", 279 | "label": "Germany" 280 | } 281 | ] 282 | } 283 | ] 284 | } 285 | } 286 | ``` 287 | {% endtab %} 288 | 289 | {% tab title="Select field that allows to pick multiple options" %} 290 | ```typescript 291 | { 292 | "view": { 293 | "type": "form", 294 | "fields": [ 295 | { 296 | "type": "select", 297 | "id": "country", 298 | "label": "Where do you want to travel to?", 299 | "multiple": true, 300 | "placeholder": "Select Countries", 301 | "options": [ 302 | "Ukraine", 303 | "Spain", 304 | "Germany" 305 | ] 306 | } 307 | ] 308 | } 309 | } 310 | ``` 311 | {% endtab %} 312 | {% endtabs %} 313 | -------------------------------------------------------------------------------- /docs/reference/command-response-view-list.md: -------------------------------------------------------------------------------- 1 | # List View 2 | 3 | The List View response tells the Command Bar to display a list of options. 4 | 5 | * **type:** `"list"` 6 | * **options:** An array of [ListOption](command-response-view-list.md#listoption) objects. 7 | * **groups:** Optional. An array of [Group](command-response-view-list.md#group) objects (or strings). Can be used to define the order in which they appear and customize how they are displayed. 8 | * **ranking:** Optional. The default value is `true`, i.e the Command Bar's default ranking will be used. If you wish to return different options as the user types in the Command Bar, set `ranking` to `false`. Then Slapdash will run your command with a special parameter `keywords` that you can use to decide what options to return back. 9 | 10 | {% tabs %} 11 | {% tab title="Options to open, copy, paste a URL or show it in a toast" %} 12 | ```typescript 13 | { 14 | "view": { 15 | "type": "list", 16 | "options": [ 17 | { 18 | "title": "Open Google", 19 | "action": { 20 | "type": "open-url", 21 | "url": "https://www.google.com/" 22 | } 23 | }, 24 | { 25 | "title": "Copy Google URL", 26 | "action": { 27 | "type": "copy", 28 | "value": "https://www.google.com/" 29 | } 30 | }, 31 | { 32 | "title": "Paste Google URL", 33 | "action": { 34 | "type": "paste", 35 | "value": "https://www.google.com/" 36 | } 37 | }, 38 | { 39 | "title": "Show Google URL", 40 | "action": { 41 | "type": "show-toast", 42 | "message": "https://www.google.com/" 43 | } 44 | } 45 | ] 46 | } 47 | } 48 | ``` 49 | {% endtab %} 50 | 51 | {% tab title="Grouped options" %} 52 | ```typescript 53 | { 54 | "view": { 55 | "type": "list", 56 | "groups": ["Clipboard", "Browser", "Misc"], 57 | "options": [ 58 | { 59 | "title": "Open Google", 60 | "group": "Browser", 61 | "action": { 62 | "type": "open-url", 63 | "url": "https://www.google.com/" 64 | } 65 | }, 66 | { 67 | "title": "Copy Google URL", 68 | "group": "Clipboard", 69 | "action": { 70 | "type": "copy", 71 | "value": "https://www.google.com/" 72 | } 73 | }, 74 | { 75 | "title": "Paste Google URL", 76 | "group": "Clipboard", 77 | "action": { 78 | "type": "paste", 79 | "value": "https://www.google.com/" 80 | } 81 | }, 82 | { 83 | "title": "Show Google URL", 84 | "group": "Misc", 85 | "action": { 86 | "type": "show-toast", 87 | "message": "https://www.google.com/" 88 | } 89 | } 90 | ] 91 | } 92 | } 93 | ``` 94 | {% endtab %} 95 | {% endtabs %} 96 | 97 | ## ListOption 98 | 99 | Property `CommandResponse.view.options` is the list of options that are displayed in the List View. 100 | 101 | * **title:** The title for the option. 102 | * **action:** Option's [Main Action](command-response-view-list.md#options-main-action). This Action is executed when **`Enter`** is pressed on the Option (or when the option is clicked). 103 | * **moveAction:** Optional. Option's [Move Action](command-response-view-list.md#options-move-action) object. This Action is executed when Tab is pressed on the Option. 104 | * **icon**: Optional. The [Icon](command-response-icon.md) for the option. 105 | * **subtitle:** Optional. The subtitle for the option. Can be provided as a string or a list of strings. 106 | * **group:** Optional. The [Group](command-response-view-list.md#group) this option belongs to. 107 | 108 | {% tabs %} 109 | {% tab title="List View: options with a custom icon and subtitle" %} 110 | ```typescript 111 | { 112 | "view": { 113 | "type": "list", 114 | "options": [ 115 | { 116 | "title": "Copy Home Number", 117 | "subtitle": [ 118 | "Mobile", 119 | "Emergencies" 120 | ], 121 | "group": "Phone Numbers", 122 | "icon": "🏠", 123 | "action": { 124 | "type": "copy", 125 | "value": "+44123456789" 126 | } 127 | }, 128 | { 129 | "title": "Copy Work Number", 130 | "subtitle": [ 131 | "Stationary", 132 | "9-5" 133 | ], 134 | "group": "Phone Numbers", 135 | "icon": "💼", 136 | "action": { 137 | "type": "copy", 138 | "value": "+44987654321" 139 | } 140 | } 141 | ] 142 | } 143 | } 144 | ``` 145 | {% endtab %} 146 | {% endtabs %} 147 | 148 | ## Group 149 | 150 | Property `CommandResponse.view.groups` allows to display options in the List View in groups. Each `Group` can be a string or an object. Provide Group as an object if you want to customize its appearance (e.g. change its title). 151 | 152 | {% tabs %} 153 | {% tab title="List View: custom order for groups" %} 154 | ```typescript 155 | { 156 | "view": { 157 | "type": "list", 158 | "groups": [ 159 | "misc", 160 | "browser", 161 | "clipboard" 162 | ], 163 | "options": [ 164 | { 165 | "title": "Open Google", 166 | "group": "browser", 167 | "action": { 168 | "type": "open-url", 169 | "url": "https://www.google.com/" 170 | } 171 | }, 172 | { 173 | "title": "Copy Google URL", 174 | "group": "clipboard", 175 | "action": { 176 | "type": "copy", 177 | "value": "https://www.google.com/" 178 | } 179 | }, 180 | { 181 | "title": "Paste Google URL", 182 | "group": "clipboard", 183 | "action": { 184 | "type": "paste", 185 | "value": "https://www.google.com/" 186 | } 187 | }, 188 | { 189 | "title": "Show Google URL", 190 | "group": "misc", 191 | "action": { 192 | "type": "show-toast", 193 | "message": "https://www.google.com/" 194 | } 195 | } 196 | ] 197 | } 198 | } 199 | ``` 200 | {% endtab %} 201 | 202 | {% tab title="List View: custom title for a group" %} 203 | ```typescript 204 | { 205 | "view": { 206 | "type": "list", 207 | "groups": [ 208 | { 209 | "id": "misc", 210 | "title": "Miscellaneous" 211 | }, 212 | "browser", 213 | "clipboard" 214 | ], 215 | "options": [ 216 | { 217 | "title": "Open Google", 218 | "group": "browser", 219 | "action": { 220 | "type": "open-url", 221 | "url": "https://www.google.com/" 222 | } 223 | }, 224 | { 225 | "title": "Copy Google URL", 226 | "group": "clipboard", 227 | "action": { 228 | "type": "copy", 229 | "value": "https://www.google.com/" 230 | } 231 | }, 232 | { 233 | "title": "Paste Google URL", 234 | "group": "clipboard", 235 | "action": { 236 | "type": "paste", 237 | "value": "https://www.google.com/" 238 | } 239 | }, 240 | { 241 | "title": "Show Google URL", 242 | "group": "misc", 243 | "action": { 244 | "type": "show-toast", 245 | "message": "https://www.google.com/" 246 | } 247 | } 248 | ] 249 | } 250 | } 251 | ``` 252 | {% endtab %} 253 | {% endtabs %} 254 | 255 | ## Option's Main Action 256 | 257 | The Main Action for an Option can be provided as the plain [Action](command-response-action.md) object or as a special object that allows to customize how the action is visualised by the Command Bar. 258 | 259 | ```typescript 260 | type OptionMainAction = 261 | | Action 262 | | { 263 | /** The default Action object. */ 264 | action: Action; 265 | /** The label for this action. By default it will be inferred 266 | * from the action property. */ 267 | label?: string; 268 | /** The tooltip for this action. By default it will be inferred 269 | * from the action property. */ 270 | tooltip?: string; 271 | /** The icon for this action. Either an emoji or an Image URL. 272 | * By default it will be inferred from the action property. */ 273 | icon?: Icon; 274 | }; 275 | ``` 276 | 277 | {% tabs %} 278 | {% tab title="List View: custom affordances for the option" %} 279 | ```typescript 280 | { 281 | "view": { 282 | "type": "list", 283 | "options": [ 284 | { 285 | "title": "Open Google", 286 | "action": { 287 | "label": "Open Browser", 288 | "icon": "🌎", 289 | "tooltip": "Open Google in the Browser", 290 | "action": { 291 | "type": "open-url", 292 | "url": "https://www.google.com/" 293 | } 294 | } 295 | } 296 | ] 297 | } 298 | } 299 | ``` 300 | {% endtab %} 301 | 302 | {% tab title="List View: default affordances for the option" %} 303 | ```typescript 304 | { 305 | "view": { 306 | "type": "list", 307 | "options": [ 308 | { 309 | "title": "Open Google", 310 | "action": { 311 | "type": "open-url", 312 | "url": "https://www.google.com/" 313 | } 314 | } 315 | ] 316 | } 317 | } 318 | ``` 319 | {% endtab %} 320 | {% endtabs %} 321 | 322 | ## Option's Move Action 323 | 324 | Property `CommandResponse.view.options[].moveAction` allows providing a [Move Action](command-response-action.md#actionmoveaddparam) to change the location of the Command Bar. 325 | 326 | {% tabs %} 327 | {% tab title="Masonry View: option with " %} 328 | ```typescript 329 | { 330 | "view": { 331 | "type": "masonry", 332 | "options": [ 333 | { 334 | "imageURL": "https://images.unsplash.com/photo-1481819613568-3701cbc70156", 335 | "action": { 336 | "type": "open-url", 337 | "url": "https://images.unsplash.com/photo-1481819613568-3701cbc70156" 338 | }, 339 | "moveAction": { 340 | "type": "add-param", 341 | "name": "image", 342 | "value": "moon" 343 | } 344 | } 345 | ] 346 | } 347 | } 348 | ``` 349 | {% endtab %} 350 | {% endtabs %} 351 | -------------------------------------------------------------------------------- /docs/reference/command-response-view-masonry.md: -------------------------------------------------------------------------------- 1 | # Masonry View 2 | 3 | The Masonry View response tells the Command Bar to displays options in the Pinterest-like layout. 4 | 5 | * **type:** `"masonry"` 6 | * **options:** An array of [MasonryOption](command-response-view-masonry.md#masonryoption) objects. 7 | 8 | ```javascript 9 | { 10 | "view": { 11 | "type": "masonry", 12 | "options": [ 13 | { 14 | "imageURL": "https://images.unsplash.com/photo-1481819613568-3701cbc70156", 15 | "action": { 16 | "type": "copy", 17 | "value": "Moon" 18 | } 19 | }, 20 | { 21 | "imageURL": "https://images.unsplash.com/photo-1614642264762-d0a3b8bf3700", 22 | "action": { 23 | "type": "copy", 24 | "value": "Sun" 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | ``` 31 | 32 | ## MasonryOption 33 | 34 | For MasonryView, property `CommandResponse.view.options` contains the list of MasonryOption objects. 35 | 36 | * **imageURL:** The image URL for this option. 37 | * **action:** Option's [Main Action](command-response-view-list.md#options-main-action) object. 38 | * **moveAction:** Optional. Option's [Move Action](command-response-view-list.md#options-move-action) object. 39 | 40 | ```javascript 41 | { 42 | "view": { 43 | "type": "masonry", 44 | "options": [ 45 | { 46 | "imageURL": "https://images.unsplash.com/photo-1481819613568-3701cbc70156", 47 | "action": { 48 | "type": "open-url", 49 | "url": "https://images.unsplash.com/photo-1481819613568-3701cbc70156" 50 | }, 51 | "moveAction": { 52 | "type": "add-param", 53 | "name": "image", 54 | "value": "moon" 55 | } 56 | }, 57 | { 58 | "imageURL": "https://images.unsplash.com/photo-1512361180836-1ecddb33f2dd", 59 | "action": { 60 | "type": "copy", 61 | "value": "Sky" 62 | } 63 | } 64 | ] 65 | } 66 | } 67 | ``` 68 | 69 | -------------------------------------------------------------------------------- /docs/reference/command-response-view.md: -------------------------------------------------------------------------------- 1 | # View 2 | 3 | Views define, what's shown to the user when the command is executed. The view can be provided at the root of the [Command Response](command-response.md) using the `CommandReponse.view` property. 4 | 5 | The simplest view one can use is text. Simply set the view property to some text and it will be shown in the Command Bar. 6 | 7 | ```javascript 8 | { 9 | "view": "Ahoy, world!" 10 | } 11 | ``` 12 | 13 | Read on about other views that can be used in the Command Response: [List](command-response-view-list.md#list), [Masonry](command-response-view-masonry.md) and [Form](command-response-view-form.md). 14 | 15 | -------------------------------------------------------------------------------- /docs/reference/command-response.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | A JSON-encoded data structure used to describe the behavior and UI of a 4 | Slapdash command. 5 | --- 6 | 7 | # Command Response 8 | 9 | A command should return a JSON that tells what the Command Bar should show or do. The JSON needs to conform to a certain format, which can be described with the TypeScript definition below. 10 | 11 | ```typescript 12 | interface CommandResponse { 13 | /** 14 | * Optional. 15 | * A side effect of the Command when it's run. 16 | */ 17 | action?: Action; 18 | 19 | /** 20 | * Optional. 21 | * The View the Command Bar should display 22 | * (List, Form etc.). 23 | */ 24 | view?: View; 25 | 26 | /** 27 | * Optional. 28 | * A way to configure the command before it can 29 | * be used. For example, to collect an API key. 30 | */ 31 | config?: Config; 32 | 33 | /** 34 | * Optional. 35 | * A way to customize how Command Bar tokens 36 | * that are visualized. 37 | */ 38 | tokens?: Token[]; 39 | 40 | /** 41 | * Optional. 42 | * The placeholder text in the Command Bar's input. 43 | */ 44 | inputPlaceholder?: string; 45 | } 46 | ``` 47 | 48 | ## Quick Examples 49 | 50 | The simplest way to experiment with commands is to copy one of the examples below to a file with `*.js` extension and then create a [Local Command](../command-bar-101/local-commands.md) in the [Slapdash desktop app](https://slapdash.com/download). 51 | 52 | {% tabs %} 53 | {% tab title="Open URL Action" %} 54 | ```javascript 55 | // https://github.com/slapdash/platform/blob/main/docs/reference/open-url.js 56 | console.log( 57 | JSON.stringify({ 58 | action: { 59 | type: "open-url", 60 | url: "https://slapdash.com/", 61 | }, 62 | }) 63 | ); 64 | ``` 65 | 66 | When selected in the Command Bar, the command just opens a particular URL in the browser: 67 | 68 | ![](../.gitbook/assets/screen-shot-2021-06-11-at-8.31.38-pm.png) 69 | {% endtab %} 70 | 71 | {% tab title="List View" %} 72 | ```javascript 73 | // https://github.com/slapdash/platform/blob/main/docs/reference/list-view.js 74 | console.log( 75 | JSON.stringify({ 76 | view: { 77 | type: "list", 78 | options: [ 79 | { 80 | title: "Open Google", 81 | action: { 82 | type: "open-url", 83 | url: "https://www.google.com/", 84 | }, 85 | }, 86 | { 87 | title: "Open Bing", 88 | action: { 89 | type: "open-url", 90 | url: "https://www.bing.com/", 91 | }, 92 | }, 93 | ], 94 | }, 95 | }) 96 | ); 97 | ``` 98 | 99 | The command shows the list of options. Each option has an associated Action \(in this example, the actions are to open URLs\): 100 | 101 | ![](../.gitbook/assets/screen-shot-2021-06-11-at-8.30.10-pm.png) 102 | {% endtab %} 103 | 104 | {% tab title="Masonry View" %} 105 | ```javascript 106 | // https://github.com/slapdash/platform/blob/main/docs/reference/masonry-view.js 107 | console.log( 108 | JSON.stringify({ 109 | view: { 110 | type: "masonry", 111 | options: [ 112 | { 113 | imageURL: 114 | "https://images.unsplash.com/photo-1481819613568-3701cbc70156", 115 | action: { 116 | type: "copy", 117 | value: "Moon", 118 | }, 119 | }, 120 | { 121 | imageURL: 122 | "https://images.unsplash.com/photo-1614642264762-d0a3b8bf3700", 123 | action: { 124 | type: "copy", 125 | value: "Sun", 126 | }, 127 | }, 128 | { 129 | imageURL: 130 | "https://images.unsplash.com/photo-1512361180836-1ecddb33f2dd", 131 | action: { 132 | type: "copy", 133 | value: "Sky", 134 | }, 135 | }, 136 | ], 137 | }, 138 | }) 139 | ); 140 | ``` 141 | 142 | Similar to the List View, but shows the images in a Masonry grid: 143 | 144 | ![](../.gitbook/assets/screen-shot-2021-06-11-at-8.28.52-pm.png) 145 | {% endtab %} 146 | 147 | {% tab title="Form View" %} 148 | ```javascript 149 | // https://github.com/slapdash/platform/blob/main/docs/reference/form-view.js 150 | console.log( 151 | JSON.stringify({ 152 | view: { 153 | type: "form", 154 | title: "Order Drink", 155 | submitLabel: "Order", 156 | fields: [ 157 | { 158 | type: "text", 159 | id: "name", 160 | label: "Your Name", 161 | }, 162 | { 163 | type: "select", 164 | id: "drink", 165 | label: "Drink", 166 | options: ["Cappuccino", "Latte", "Green Tea", "Coke"], 167 | }, 168 | ], 169 | }, 170 | }) 171 | ); 172 | ``` 173 | 174 | The command shows a form and allows the user to enter some data. When the form is submitted, the command is run again, and the entered data is passed as JSON to its STDIN. 175 | 176 | ![](../.gitbook/assets/screen-shot-2021-06-11-at-8.28.24-pm.png) 177 | {% endtab %} 178 | 179 | {% tab title="Custom Config" %} 180 | ```javascript 181 | // https://github.com/slapdash/platform/blob/main/docs/reference/custom-config.js 182 | console.log( 183 | JSON.stringify({ 184 | config: { 185 | form: { 186 | fields: [ 187 | { 188 | type: "text", 189 | id: "api-key", 190 | label: "API Key", 191 | placeholder: "GIPHY API key", 192 | }, 193 | ], 194 | }, 195 | }, 196 | }) 197 | ); 198 | ``` 199 | 200 | Emitting `config` property allows the command to request some private configuration data from the user when it is first executed. Later, the configuration is passed back to the command via process environment variables. 201 | 202 | ![](../.gitbook/assets/screen-shot-2021-06-11-at-8.27.53-pm.png) 203 | {% endtab %} 204 | {% endtabs %} 205 | 206 | -------------------------------------------------------------------------------- /docs/reference/custom-config.js: -------------------------------------------------------------------------------- 1 | console.log(JSON.stringify({ 2 | "config": { 3 | "form": { 4 | "fields": [ 5 | { 6 | "type": "text", 7 | "id": "api-key", 8 | "label": "API Key", 9 | "placeholder": "GIPHY API key" 10 | } 11 | ] 12 | } 13 | } 14 | })); 15 | -------------------------------------------------------------------------------- /docs/reference/form-view.js: -------------------------------------------------------------------------------- 1 | console.log(JSON.stringify({ 2 | "view": { 3 | "type": "form", 4 | "title": "Order Drink", 5 | "submitLabel": "Order", 6 | "fields": [ 7 | { 8 | "type": "text", 9 | "id": "name", 10 | "label": "Your Name" 11 | }, 12 | { 13 | "type": "select", 14 | "id": "drink", 15 | "label": "Drink", 16 | "options": [ 17 | "Cappuccino", 18 | "Latte", 19 | "Green Tea", 20 | "Coke" 21 | ] 22 | } 23 | ] 24 | } 25 | })); 26 | -------------------------------------------------------------------------------- /docs/reference/list-view.js: -------------------------------------------------------------------------------- 1 | console.log(JSON.stringify({ 2 | "view": { 3 | "type": "list", 4 | "options": [ 5 | { 6 | "title": "Open Google", 7 | "action": { 8 | "type": "open-url", 9 | "url": "https://www.google.com/" 10 | } 11 | }, 12 | { 13 | "title": "Open Bing", 14 | "action": { 15 | "type": "open-url", 16 | "url": "https://www.bing.com/" 17 | } 18 | } 19 | ] 20 | } 21 | })); 22 | -------------------------------------------------------------------------------- /docs/reference/masonry-view.js: -------------------------------------------------------------------------------- 1 | console.log(JSON.stringify({ 2 | "view": { 3 | "type": "masonry", 4 | "options": [ 5 | { 6 | "imageURL": "https://images.unsplash.com/photo-1481819613568-3701cbc70156", 7 | "action": { 8 | "type": "copy", 9 | "value": "Moon" 10 | } 11 | }, 12 | { 13 | "imageURL": "https://images.unsplash.com/photo-1614642264762-d0a3b8bf3700", 14 | "action": { 15 | "type": "copy", 16 | "value": "Sun" 17 | } 18 | }, 19 | { 20 | "imageURL": "https://images.unsplash.com/photo-1512361180836-1ecddb33f2dd", 21 | "action": { 22 | "type": "copy", 23 | "value": "Sky" 24 | } 25 | } 26 | ] 27 | } 28 | })); 29 | -------------------------------------------------------------------------------- /docs/reference/open-url.js: -------------------------------------------------------------------------------- 1 | console.log(JSON.stringify({ 2 | "action": { 3 | "type": "open-url", 4 | "url": "https://slapdash.com/", 5 | } 6 | })); 7 | -------------------------------------------------------------------------------- /docs/root.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Build Command Bar commands for yourself, or to share with others. 3 | --- 4 | 5 | # Ahoy, world! 6 | 7 | Welcome to the [Slapdash](https://slapdash.com) platform. To start, we're opening up a way to extend the functionality of the Slapdash Command Bar, letting you write your own commands. 8 | 9 | You can start by learning [how the Command Bar works](command-bar-101/how-it-works.md), pause to flip through the [core terminology](command-bar-101/core-terminology.md) and then have yourself a good sleep to make sure you retain what you read. 10 | 11 | Otherwise, we fully encourage you to throw caution to the wind and just [start building your first command](command-bar-101/setup-your-first-command.md). Don't think, just recklessly copy-paste these examples to your editor and see what comes out on the other side. 12 | 13 | #### **Get Help** 14 | 15 | We're here to help and if you want to reach us, just click `?` in Slapdash or the chat icon at the bottom right corner to send us a message. You can also email us at [hello@slapdash.com](mailto:hello@slapdash.com). 16 | -------------------------------------------------------------------------------- /packages/command-response-types/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### `1.0.5` — Nov 15, 2021 2 | 3 | - It's now possible to show a top-level error in the form view using the new `error` property. 4 | 5 | ### `1.0.4` — Oct 12, 2021 6 | 7 | ###### NEW 8 | 9 | - Action `"open-url"` now accepts an array of strings in `url` property. Allows to open multiple URLs at once. 10 | 11 | ### `1.0.3` — Aug 18, 2021 12 | 13 | ###### NEW 14 | 15 | - Text View. `view` can now be set to a raw string to display some text in the Command Bar. 16 | 17 | ### `1.0.2` — Aug 12, 2021 18 | 19 | ###### NEW 20 | 21 | - A new Icon type. Allows to specify different icons for dark and light themes as well as providing a monochrome icon that will be automatically adjusted to the current theme. 22 | 23 | ### `1.0.0` — June 4, 2021 24 | 25 | :tada: 26 | -------------------------------------------------------------------------------- /packages/command-response-types/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License Copyright (c) 2021 Slapdash Inc. 2 | 3 | Permission is hereby granted, free of 4 | charge, to any person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, copy, modify, merge, 7 | publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to the 9 | following conditions: 10 | 11 | The above copyright notice and this permission notice 12 | (including the next paragraph) shall be included in all copies or substantial 13 | portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO 18 | EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/command-response-types/README.md: -------------------------------------------------------------------------------- 1 | # Command Response Types 2 | 3 | TypeScript types for the [Command Response specification](https://platform.slapdash.com/reference/command-response). 4 | -------------------------------------------------------------------------------- /packages/command-response-types/index.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Root response object 3 | // 4 | 5 | export interface CommandResponse { 6 | action?: Action; 7 | view?: View; 8 | config?: Config; 9 | tokens?: Token[]; 10 | inputPlaceholder?: string; 11 | } 12 | 13 | // 14 | // Action 15 | // 16 | 17 | export type Action = 18 | | ActionOpenURL 19 | | ActionPaste 20 | | ActionCopy 21 | | ActionShowToast 22 | | ActionMove; 23 | 24 | export interface ActionOpenURL { 25 | type: "open-url"; 26 | url: string | string[]; 27 | } 28 | 29 | export interface ActionPaste { 30 | type: "paste"; 31 | value: string; 32 | } 33 | 34 | export interface ActionCopy { 35 | type: "copy"; 36 | value: string; 37 | } 38 | 39 | export interface ActionShowToast { 40 | type: "show-toast"; 41 | message: string; 42 | } 43 | 44 | export interface ActionMoveAddParam { 45 | type: "add-param"; 46 | name: string; 47 | value: string; 48 | } 49 | 50 | export type ActionMove = ActionMoveAddParam; 51 | 52 | // 53 | // View 54 | // 55 | 56 | export type View = string | List | Masonry | Form; 57 | 58 | export interface List { 59 | type: "list"; 60 | options: ListOption[]; 61 | groups?: Group[]; 62 | ranking?: Ranking; 63 | } 64 | 65 | export interface ListOption { 66 | title: string; 67 | subtitle?: string | string[]; 68 | icon?: Icon; 69 | action: OptionMainAction; 70 | moveAction?: ActionMove; 71 | group?: string; 72 | } 73 | 74 | export type OptionMainAction = 75 | | Action 76 | | { 77 | action: Action; 78 | label?: string; 79 | tooltip?: string; 80 | icon?: Icon; 81 | }; 82 | 83 | export type Group = string | GroupObject; 84 | 85 | export interface GroupObject { 86 | id: string; 87 | title: string; 88 | } 89 | 90 | export type Ranking = boolean; 91 | 92 | export interface Masonry { 93 | type: "masonry"; 94 | options: MasonryOption[]; 95 | } 96 | 97 | export type MasonryOption = Pick & { 98 | imageURL: string; 99 | }; 100 | 101 | export interface Form { 102 | type: "form"; 103 | fields: FormFields; 104 | title?: string; 105 | submitLabel?: string; 106 | cancelLabel?: string; 107 | method?: "get" | "post"; 108 | error?: string | null; 109 | } 110 | 111 | export type FormValues = { 112 | [x: string]: string | number | boolean | string[]; 113 | }; 114 | 115 | export type FormFields = Array; 116 | 117 | export type FormField = TextField | ToggleField | SelectField | DateField; 118 | 119 | export interface BaseField { 120 | id: string; 121 | required?: boolean; 122 | label: string; 123 | defaultValue?: unknown | null; 124 | error?: string | null; 125 | helpText?: string | null; 126 | } 127 | 128 | export interface TextField extends BaseField { 129 | type: "text"; 130 | placeholder?: string; 131 | defaultValue?: string | null; 132 | multiline?: boolean; 133 | } 134 | 135 | export interface ToggleField extends BaseField { 136 | type: "toggle"; 137 | defaultValue?: boolean | null; 138 | } 139 | 140 | export interface SelectField extends BaseField { 141 | type: "select"; 142 | options: SelectOption[]; 143 | multiple?: boolean; 144 | placeholder?: string; 145 | defaultValue?: string | string[] | null; 146 | } 147 | 148 | export type SelectOption = string | { label: string; value: string }; 149 | 150 | export interface DateField extends BaseField { 151 | type: "date"; 152 | timeSelect?: boolean; 153 | defaultValue?: string | null; 154 | } 155 | 156 | // 157 | // Icon 158 | // 159 | 160 | export type IconPadding = 161 | | "slapdash-system" 162 | | "none" 163 | | "material-system" 164 | | "edge-to-edge"; 165 | 166 | export type Icon = 167 | | string 168 | | { 169 | src: string; 170 | padding?: IconPadding; 171 | } 172 | | { 173 | light: string; 174 | dark: string; 175 | padding?: IconPadding; 176 | } 177 | | { 178 | monochrome: string; 179 | padding?: IconPadding; 180 | }; 181 | 182 | // 183 | // Config 184 | // 185 | 186 | export interface Config { 187 | form: Pick; 188 | } 189 | 190 | // 191 | // Token 192 | // 193 | 194 | export interface Token { 195 | paramName: string; 196 | label?: string; 197 | icon?: Icon; 198 | } 199 | -------------------------------------------------------------------------------- /packages/command-response-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@slapdash/command-response-types", 3 | "version": "1.0.5", 4 | "description": "TypeScript types for the Command Response specification.", 5 | "types": "index.d.ts", 6 | "homepage": "https://github.com/slapdash/platform/tree/main/packages/command-response-types", 7 | "keywords": [ 8 | "slapdash", 9 | "platform", 10 | "commandbar", 11 | "types" 12 | ], 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/slapdash/platform/", 16 | "directory": "packages/command-response-types" 17 | }, 18 | "author": { 19 | "name": "Slapdash Inc.", 20 | "email": "hello@slapdash.com", 21 | "url": "https://slapdash.com" 22 | }, 23 | "license": "MIT" 24 | } 25 | -------------------------------------------------------------------------------- /templates/bash/ahoy-world.sh: -------------------------------------------------------------------------------- 1 | #!bash 2 | 3 | echo '{ 4 | "view": { 5 | "type": "list", 6 | "options": [ 7 | { 8 | "title": "Open Slapdash", 9 | "action": { 10 | "type": "open-url", 11 | "url": "https://slapdash.com" 12 | } 13 | }, 14 | { 15 | "title": "Copy Heart Emoji", 16 | "action": { 17 | "type": "copy", 18 | "value": "❤️" 19 | } 20 | } 21 | ] 22 | } 23 | }' 24 | -------------------------------------------------------------------------------- /templates/custom-shebang-not-bash.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'json' 3 | 4 | print JSON.generate({ 5 | "view": { 6 | "type": "list", 7 | "options": [ 8 | { 9 | "title": "Open Slapdash", 10 | "action": { 11 | "type": "open-url", 12 | "url": "https://slapdash.com" 13 | } 14 | }, 15 | { 16 | "title": "Copy Heart Emoji", 17 | "action": { 18 | "type": "copy", 19 | "value": "❤️" 20 | } 21 | } 22 | ] 23 | } 24 | }) 25 | -------------------------------------------------------------------------------- /templates/javascript/ahoy-world.js: -------------------------------------------------------------------------------- 1 | const response = { 2 | view: { 3 | type: "list", 4 | options: [ 5 | { 6 | title: "Open Slapdash", 7 | action: { 8 | type: "open-url", 9 | url: "https://slapdash.com" 10 | } 11 | }, 12 | { 13 | title: "Copy Heart Emoji", 14 | action: { 15 | type: "copy", 16 | value: "❤️" 17 | } 18 | } 19 | ] 20 | } 21 | }; 22 | 23 | console.log(JSON.stringify(response)); 24 | -------------------------------------------------------------------------------- /templates/perl/ahoy-world.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | use utf8; 3 | use JSON; 4 | 5 | print encode_json({ 6 | "view" => { 7 | "type" => "list", 8 | "options" => [ 9 | { 10 | "title" => "Open Slapdash", 11 | "action" => { 12 | "type" => "open-url", 13 | "url" => "https://slapdash.com" 14 | } 15 | }, 16 | { 17 | "title" => "Copy Heart Emoji", 18 | "action" => { 19 | "type" => "copy", 20 | "value" => "❤️" 21 | } 22 | } 23 | ] 24 | } 25 | }) 26 | -------------------------------------------------------------------------------- /templates/php/ahoy-world.php: -------------------------------------------------------------------------------- 1 | #!php 2 | [ 5 | "type" => "list", 6 | "options" => [ 7 | [ 8 | "title" => "Open Slapdash", 9 | "action" => [ 10 | "type" => "open-url", 11 | "url" => "https://slapdash.com" 12 | ] 13 | ], 14 | [ 15 | "title" => "Copy Heart Emoji", 16 | "action" => [ 17 | "type" => "paste", 18 | "value" => "❤️" 19 | ] 20 | ] 21 | ] 22 | ] 23 | ]); 24 | -------------------------------------------------------------------------------- /templates/python/ahoy-world.py: -------------------------------------------------------------------------------- 1 | #!python 2 | # -*- coding: utf-8 -*- 3 | import json 4 | 5 | print(json.dumps({ 6 | "view": { 7 | "type": "list", 8 | "options": [ 9 | { 10 | "title": "Open Slapdash", 11 | "action": { 12 | "type": "open-url", 13 | "url": "https://slapdash.com" 14 | } 15 | }, 16 | { 17 | "title": "Copy Heart Emoji", 18 | "action": { 19 | "type": "copy", 20 | "value": "❤️" 21 | } 22 | } 23 | ] 24 | } 25 | })) 26 | -------------------------------------------------------------------------------- /templates/ruby/ahoy-world.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'json' 3 | 4 | print JSON.generate({ 5 | "view": { 6 | "type": "list", 7 | "options": [ 8 | { 9 | "title": "Open Slapdash", 10 | "action": { 11 | "type": "open-url", 12 | "url": "https://slapdash.com" 13 | } 14 | }, 15 | { 16 | "title": "Copy Heart Emoji", 17 | "action": { 18 | "type": "copy", 19 | "value": "❤️" 20 | } 21 | } 22 | ] 23 | } 24 | }) 25 | -------------------------------------------------------------------------------- /templates/typescript/global/README.md: -------------------------------------------------------------------------------- 1 | ### Globally installed ts-node 2 | 3 | Pointing Slapdash to this script assumes that you have `ts-node` installed globally on your computer: 4 | 5 | ``` 6 | npm -g install ts-node 7 | ``` 8 | -------------------------------------------------------------------------------- /templates/typescript/global/ahoy-world.ts: -------------------------------------------------------------------------------- 1 | const response = { 2 | view: { 3 | type: "list", 4 | options: [ 5 | { 6 | title: "Open Slapdash", 7 | action: { 8 | type: "open-url", 9 | url: "https://slapdash.com", 10 | }, 11 | }, 12 | { 13 | title: "Copy Heart Emoji", 14 | action: { 15 | type: "copy", 16 | value: "❤️", 17 | }, 18 | }, 19 | ], 20 | }, 21 | }; 22 | 23 | console.log(JSON.stringify(response)); 24 | -------------------------------------------------------------------------------- /templates/typescript/package/README.md: -------------------------------------------------------------------------------- 1 | ### Locally installed ts-node 2 | 3 | Pointing Slapdash to this script assumes that you previously initialized `node_modules` folder in this directory, so Slapdash will use `ts-node` from there: 4 | 5 | ``` 6 | npm install 7 | ``` 8 | -------------------------------------------------------------------------------- /templates/typescript/package/ahoy-world.ts: -------------------------------------------------------------------------------- 1 | const response = { 2 | view: { 3 | type: "list", 4 | options: [ 5 | { 6 | title: "Open Slapdash", 7 | action: { 8 | type: "open-url", 9 | url: "https://slapdash.com", 10 | }, 11 | }, 12 | { 13 | title: "Copy Heart Emoji", 14 | action: { 15 | type: "copy", 16 | value: "❤️", 17 | }, 18 | }, 19 | ], 20 | }, 21 | }; 22 | 23 | console.log(JSON.stringify(response)); 24 | -------------------------------------------------------------------------------- /templates/typescript/package/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "dependencies": { 4 | "ts-node": "*" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tutorials/copy-special-character/copy-special-character.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A command that shows special characters. Hitting Enter 3 | * will copy character, hitting Tab will give other ways 4 | * to copy the character: HTML hex code, for example. 5 | * 6 | * Follow the tutorial at https://developers.slapdash.com/command-tutorials/copy-special-character 7 | */ 8 | 9 | /** 10 | * Gets arguments passed in to script, like: --character=control 11 | * and stores it into an array, like: args['character'] = "control". 12 | */ 13 | const args = process.argv.slice(2).reduce((agg, arg) => { 14 | const match = arg.match(/^--(?\w+)=(?.+)$/); 15 | return match ? { ...agg, [match.groups.key]: match.groups.value } : agg; 16 | }, {}); 17 | 18 | let response; 19 | if (args["character"]) { 20 | response = showOptionsForCharacter(args["character"]); 21 | } else { 22 | response = showAllCharacters(); 23 | } 24 | console.log(JSON.stringify(response)); 25 | 26 | /* 27 | * The view that is shown when someone runs the command. 28 | */ 29 | function showAllCharacters() { 30 | const response = { 31 | view: { 32 | type: "list", 33 | options: [ 34 | { 35 | title: "Command", 36 | action: { 37 | type: "copy", 38 | value: "⌘", 39 | }, 40 | moveAction: { 41 | type: "add-param", 42 | name: "character", 43 | value: "command", 44 | }, 45 | }, 46 | { 47 | title: "Option", 48 | action: { 49 | type: "copy", 50 | value: "⌥", 51 | }, 52 | moveAction: { 53 | type: "add-param", 54 | name: "character", 55 | value: "option", 56 | }, 57 | }, 58 | { 59 | title: "Control", 60 | action: { 61 | type: "copy", 62 | value: "️️⌃", 63 | }, 64 | moveAction: { 65 | type: "add-param", 66 | name: "character", 67 | value: "control", 68 | }, 69 | }, 70 | ], 71 | }, 72 | }; 73 | return response; 74 | } 75 | 76 | /** 77 | * The view that is shown when someone Tabs on a character. 78 | */ 79 | function showOptionsForCharacter(character) { 80 | const charactersToHex = { 81 | command: "⌘", 82 | option: "⌥", 83 | control: "⌃", 84 | }; 85 | const characters = { 86 | command: "⌘", 87 | option: "⌥", 88 | control: "⌃", 89 | }; 90 | return { 91 | tokens: [ 92 | { 93 | paramName: "character", 94 | label: character, 95 | icon: "🎹", 96 | }, 97 | ], 98 | view: { 99 | type: "list", 100 | options: [ 101 | { 102 | title: "Copy Character", 103 | action: { 104 | type: "copy", 105 | value: characters[character], 106 | }, 107 | }, 108 | { 109 | title: "Copy Hex", 110 | action: { 111 | type: "copy", 112 | value: charactersToHex[character], 113 | }, 114 | }, 115 | ], 116 | }, 117 | }; 118 | } 119 | -------------------------------------------------------------------------------- /tutorials/emoji-paster/emoji-paster.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A command that shows a selection of emojis and pastes 3 | * the selected emoji on pressing Enter. 4 | * 5 | * Follow the tutorial at https://developers.slapdash.com/command-tutorials/emoji-paster 6 | */ 7 | 8 | const response = { 9 | view: { 10 | type: "list", 11 | options: [ 12 | { 13 | title: "Heart", 14 | action: { 15 | type: "paste", 16 | value: "❤️", 17 | }, 18 | icon: "❤️" 19 | }, 20 | { 21 | title: "Star", 22 | action: { 23 | type: "paste", 24 | value: "⭐️", 25 | }, 26 | icon: "⭐️" 27 | }, 28 | { 29 | title: "Lightning", 30 | action: { 31 | type: "paste", 32 | value: "️⚡️", 33 | }, 34 | icon: "⚡️" 35 | }, 36 | ], 37 | }, 38 | }; 39 | 40 | console.log(JSON.stringify(response)); 41 | -------------------------------------------------------------------------------- /tutorials/toggle-dark-mode/toggle-dark-mode.applescript: -------------------------------------------------------------------------------- 1 | # Follow the tutorial at https://developers.slapdash.com/command-tutorials/toggle-dark-mode 2 | 3 | tell application "System Events" 4 | tell appearance preferences 5 | set dark mode to not dark mode 6 | end tell 7 | end tell 8 | --------------------------------------------------------------------------------