├── .gitignore ├── assets ├── demo.gif ├── logo.png └── command.png ├── eslint.config.mjs ├── .prettierrc ├── .vscodeignore ├── .vscode ├── extensions.json ├── settings.json ├── tasks.json └── launch.json ├── src ├── contants │ └── index.ts ├── types │ └── index.ts ├── api │ └── index.ts └── extension.ts ├── tsconfig.json ├── commitlint.config.js ├── README.md ├── LICENSE ├── CHANGELOG.md └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | dist 3 | node_modules 4 | .vscode-test/ 5 | *.vsix 6 | .DS_Store -------------------------------------------------------------------------------- /assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/massCodeIO/assistant-vscode/HEAD/assets/demo.gif -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/massCodeIO/assistant-vscode/HEAD/assets/logo.png -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import antfu from '@antfu/eslint-config' 2 | 3 | export default antfu() 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "trailingComma": "none" 5 | } 6 | -------------------------------------------------------------------------------- /assets/command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/massCodeIO/assistant-vscode/HEAD/assets/command.png -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | src/** 4 | .gitignore 5 | .yarnrc 6 | vsc-extension-quickstart.md 7 | **/tsconfig.json 8 | **/.eslintrc.json 9 | **/*.map 10 | **/*.ts 11 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": ["dbaeumer.vscode-eslint"] 5 | } 6 | -------------------------------------------------------------------------------- /src/contants/index.ts: -------------------------------------------------------------------------------- 1 | export const MESSAGES = { 2 | ERROR: 'massCode app is not running or port is not correct.', 3 | SUCCESS: 'Snippet successfully created.', 4 | NO_CONTENT: 'No content to create a snippet from.', 5 | } 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "lib": [ 5 | "ES2022" 6 | ], 7 | "rootDir": "src", 8 | "module": "CommonJS", 9 | "moduleResolution": "node", 10 | "strict": true, 11 | "outDir": "out", 12 | "sourceMap": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'type-enum': [ 5 | 2, 6 | 'always', 7 | [ 8 | 'build', 9 | 'chore', 10 | 'docs', 11 | 'feat', 12 | 'fix', 13 | 'polish', 14 | 'refactor', 15 | 'release', 16 | 'revert', 17 | 'style', 18 | 'test', 19 | 'types', 20 | ], 21 | ], 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off" 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # massCode assistant fo Visual Studio Code 2 | 3 | > **Version Compatibility:** 4 | > - v2.0.0+ supports massCode v4 only 5 | > - For massCode v3, install extension version below v2.0.0 6 | > - Required minimum massCode version: v2.4.0 7 | 8 | Quick access to massCode app 9 | 10 | ![](https://github.com/massCodeIO/assistant-vscode/raw/master/assets/command.png) 11 | 12 | - Fetch snippets 13 | - Search snippets 14 | - Select to paste 15 | - Create snippets 16 | 17 | ![](https://github.com/massCodeIO/assistant-vscode/raw/master/assets/demo.gif) 18 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | import type { QuickPickItem } from 'vscode' 2 | 3 | export interface Snippet { 4 | id: number 5 | name: string 6 | description: string | null 7 | tags: { 8 | id: number 9 | name: string 10 | }[] 11 | folder: { 12 | id: number 13 | name: string 14 | } | null 15 | contents: { 16 | id: number 17 | label: string 18 | value: string | null 19 | language: string 20 | }[] 21 | isFavorites: number 22 | isDeleted: number 23 | createdAt: number 24 | updatedAt: number 25 | } 26 | 27 | export interface SnippetWithMeta extends QuickPickItem { 28 | meta: { 29 | snippedId: number 30 | contentId: number 31 | contentValue: string 32 | } 33 | } 34 | 35 | export interface SnippetsAdd { 36 | name: string 37 | folderId: number | null 38 | } 39 | 40 | export interface SnippetContentsAdd { 41 | label: string 42 | value: string | null 43 | language: string 44 | } 45 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "args": ["--extensionDevelopmentPath=${workspaceFolder}"], 13 | "outFiles": ["${workspaceFolder}/out/**/*.js"], 14 | "preLaunchTask": "${defaultBuildTask}" 15 | }, 16 | { 17 | "name": "Extension Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "args": [ 21 | "--extensionDevelopmentPath=${workspaceFolder}", 22 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 23 | ], 24 | "outFiles": ["${workspaceFolder}/out/test/**/*.js"], 25 | "preLaunchTask": "${defaultBuildTask}" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Anton Reshetov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/api/index.ts: -------------------------------------------------------------------------------- 1 | import type { KyInstance } from 'ky' 2 | import type { Snippet, SnippetContentsAdd, SnippetsAdd } from '../types/' 3 | import ky from 'ky' 4 | import * as vscode from 'vscode' 5 | 6 | const apiCache = new Map() 7 | 8 | function getApiClient(): KyInstance { 9 | const port = vscode.workspace 10 | .getConfiguration('masscode-assistant') 11 | .get('port', 4321) 12 | 13 | if (!apiCache.has(port)) { 14 | apiCache.set( 15 | port, 16 | ky.create({ 17 | prefixUrl: `http://localhost:${port}`, 18 | }), 19 | ) 20 | } 21 | 22 | return apiCache.get(port)! 23 | } 24 | 25 | vscode.workspace.onDidChangeConfiguration((e) => { 26 | if (e.affectsConfiguration('masscode-assistant.port')) { 27 | apiCache.clear() 28 | } 29 | }) 30 | 31 | export function getSnippets() { 32 | return getApiClient() 33 | .get('snippets', { searchParams: { isDeleted: 0 } }) 34 | .json() 35 | } 36 | 37 | export function addSnippet(body: SnippetsAdd) { 38 | return getApiClient().post<{ id: number }>('snippets', { json: body }).json() 39 | } 40 | 41 | export function addSnippetContent(snippetId: number, body: SnippetContentsAdd) { 42 | return getApiClient() 43 | .post<{ id: number }>(`snippets/${snippetId}/contents`, { json: body }) 44 | .json() 45 | } 46 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [2.0.0](https://github.com/massCodeIO/assistant-vscode/compare/v1.1.0...v2.0.0) (2025-06-30) 2 | 3 | BREAKING CHANGE: 4 | 5 | - Dropped support for massCode v3 due to API and architecture changes. 6 | - Updated dependencies and configurations to align with massCode v4 requirements. 7 | 8 | 9 | # [1.1.0](https://github.com/massCodeIO/assistant-vscode/compare/v1.0.2...v1.1.0) (2022-08-19) 10 | 11 | 12 | ### Features 13 | 14 | * add ability to choose from multiple fragments ([#7](https://github.com/massCodeIO/assistant-vscode/issues/7)) ([5061e3b](https://github.com/massCodeIO/assistant-vscode/commit/5061e3bd076ba1e1fb4686971842fde0f3f3801c)) 15 | * add last selected snippet to top of list ([2bfda66](https://github.com/massCodeIO/assistant-vscode/commit/2bfda6656b14ecd9c5c9528f382cb2f42669c9c7)) 16 | * sort snippet by date created ([9efea0b](https://github.com/massCodeIO/assistant-vscode/commit/9efea0b2f0c1c5e3ba9c9a65fba973c1777c2b87)) 17 | 18 | 19 | 20 | ## [1.0.2](https://github.com/massCodeIO/assistant-vscode/compare/v1.0.1...v1.0.2) (2022-05-04) 21 | 22 | 23 | ### Bug Fixes 24 | 25 | * exclude deleted snippets from fetch ([9dca298](https://github.com/massCodeIO/assistant-vscode/commit/9dca2980094bee62cb51fe2136390995b2c1be04)) 26 | 27 | 28 | 29 | ## [1.0.1](https://github.com/massCodeIO/assistant-vscode/compare/v1.0.0...v1.0.1) (2022-04-27) 30 | 31 | 32 | 33 | # 1.0.0 (2022-04-27) 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "publisher": "AntonReshetov", 3 | "name": "masscode-assistant", 4 | "displayName": "massCode assistant", 5 | "version": "2.0.1", 6 | "description": "Fetch snippets from massCode app and create new ones", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/massCodeIO/assistant-vscode" 10 | }, 11 | "categories": [ 12 | "Other" 13 | ], 14 | "main": "./out/extension.js", 15 | "icon": "assets/logo.png", 16 | "engines": { 17 | "vscode": "^1.96.0" 18 | }, 19 | "activationEvents": [], 20 | "contributes": { 21 | "commands": [ 22 | { 23 | "command": "masscode-assistant.search", 24 | "title": "massCode: Search" 25 | }, 26 | { 27 | "command": "masscode-assistant.create", 28 | "title": "massCode: Create Snippet" 29 | } 30 | ], 31 | "configuration": { 32 | "title": "massCode Assistant", 33 | "properties": { 34 | "masscode-assistant.notify": { 35 | "type": "boolean", 36 | "default": true, 37 | "description": "Show notification" 38 | }, 39 | "masscode-assistant.port": { 40 | "type": "number", 41 | "default": 4321, 42 | "description": "Port number for massCode API" 43 | } 44 | } 45 | } 46 | }, 47 | "scripts": { 48 | "vscode:prepublish": "npm run compile", 49 | "compile": "tsc -p ./", 50 | "watch": "tsc -watch -p ./", 51 | "pretest": "npm run compile && pnpm run lint", 52 | "package": "vsce package", 53 | "publish": "vsce publish", 54 | "lint": "eslint src", 55 | "lint:fix": "eslint src --fix", 56 | "release": "bumpp -c 'build: release v' -t", 57 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0", 58 | "prepare": "simple-git-hooks" 59 | }, 60 | "dependencies": { 61 | "ky": "^1.8.1" 62 | }, 63 | "devDependencies": { 64 | "@antfu/eslint-config": "^4.16.1", 65 | "@commitlint/cli": "^16.3.0", 66 | "@commitlint/config-conventional": "^16.2.4", 67 | "@types/mocha": "^10.0.10", 68 | "@types/node": "~20.19.2", 69 | "@types/vscode": "^1.96.0", 70 | "@typescript-eslint/eslint-plugin": "^8.35.0", 71 | "@typescript-eslint/parser": "^8.35.0", 72 | "@vscode/test-cli": "^0.0.10", 73 | "@vscode/test-electron": "^2.5.2", 74 | "bumpp": "^10.2.0", 75 | "eslint": "^9.30.0", 76 | "lint-staged": "^16.1.2", 77 | "prettier": "^3.6.2", 78 | "simple-git-hooks": "^2.13.0", 79 | "typescript": "^5.8.3" 80 | }, 81 | "volta": { 82 | "node": "20.16.0" 83 | }, 84 | "simple-git-hooks": { 85 | "pre-commit": "npx lint-staged", 86 | "commit-msg": "npx commitlint --edit $1" 87 | }, 88 | "lint-staged": { 89 | "*.{js,ts,vue}": [ 90 | "prettier --write", 91 | "eslint --fix" 92 | ] 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import type { SnippetsAdd, SnippetWithMeta } from './types' 2 | import * as vscode from 'vscode' 3 | import { addSnippet, addSnippetContent, getSnippets } from './api' 4 | import { MESSAGES } from './contants' 5 | 6 | export function activate(context: vscode.ExtensionContext) { 7 | const search = vscode.commands.registerCommand( 8 | 'masscode-assistant.search', 9 | async () => { 10 | try { 11 | const data = await getSnippets() 12 | 13 | const lastSelectedId = context.globalState.get('masscode:last-selected') 14 | 15 | const options = data.reduce((acc: SnippetWithMeta[], snippet) => { 16 | snippet.contents.forEach((content) => { 17 | acc.push({ 18 | label: snippet.name, 19 | detail: `${content.label} • ${content.language}`, 20 | description: `${snippet.folder?.name || 'Inbox'}`, 21 | picked: lastSelectedId === content.id, 22 | meta: { 23 | snippedId: snippet.id, 24 | contentId: content.id, 25 | contentValue: content.value || '', 26 | }, 27 | }) 28 | }) 29 | return acc 30 | }, []) 31 | 32 | const latestPicked = options.find(i => i.picked) 33 | 34 | if (latestPicked) { 35 | options.sort(i => (i.picked ? -1 : 1)) 36 | options.unshift({ 37 | ...latestPicked, 38 | kind: -1, 39 | label: 'Last selected', 40 | }) 41 | } 42 | 43 | const picked = await vscode.window.showQuickPick(options, { 44 | placeHolder: 'Type to search...', 45 | }) 46 | 47 | if (picked) { 48 | vscode.env.clipboard.writeText(picked.meta.contentValue) 49 | vscode.commands.executeCommand('editor.action.clipboardPasteAction') 50 | context.globalState.update( 51 | 'masscode:last-selected', 52 | picked.meta.contentId, 53 | ) 54 | } 55 | } 56 | catch (err) { 57 | console.error(err) 58 | vscode.window.showErrorMessage(MESSAGES.ERROR) 59 | } 60 | }, 61 | ) 62 | 63 | const create = vscode.commands.registerCommand( 64 | 'masscode-assistant.create', 65 | async () => { 66 | const preferences 67 | = vscode.workspace.getConfiguration('masscode-assistant') 68 | const isNotify = preferences.get('notify') 69 | 70 | const editor = vscode.window.activeTextEditor 71 | 72 | let content = '' 73 | 74 | if (editor) { 75 | const selection = editor.selection 76 | content = editor.document.getText(selection).trim() 77 | } 78 | 79 | if (content.length <= 1) { 80 | vscode.window.showErrorMessage(MESSAGES.NO_CONTENT) 81 | return 82 | } 83 | 84 | const name = await vscode.window.showInputBox() 85 | 86 | if (!name) 87 | return 88 | 89 | const body: SnippetsAdd = { 90 | name, 91 | folderId: null, 92 | } 93 | 94 | try { 95 | const { id } = await addSnippet(body) 96 | 97 | if (id) { 98 | await addSnippetContent(id, { 99 | label: 'Fragment 1', 100 | value: content, 101 | language: 'plain_text', 102 | }) 103 | } 104 | 105 | if (isNotify) { 106 | vscode.window.showInformationMessage(MESSAGES.SUCCESS) 107 | } 108 | } 109 | catch (err) { 110 | console.error(err) 111 | vscode.window.showErrorMessage(MESSAGES.ERROR) 112 | } 113 | }, 114 | ) 115 | 116 | context.subscriptions.push(search) 117 | context.subscriptions.push(create) 118 | } 119 | 120 | export function deactivate() {} 121 | --------------------------------------------------------------------------------