UNPKG

@synstack/reforge

Version:

Runtime tools for interactive DevX with the ReForge IDE extension

559 lines (553 loc) 17.3 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/reforge.index.ts var reforge_index_exports = {}; __export(reforge_index_exports, { RESPONSE_SUFFIX: () => RESPONSE_SUFFIX, baseResponseSchema: () => baseResponseSchema, getFocusedFile: () => getFocusedFile, getFocusedFileConfig: () => getFocusedFileConfig, getFocusedFileSelections: () => getFocusedFileSelections, getFocusedFileSelectionsConfig: () => getFocusedFileSelectionsConfig, getIpcClient: () => getIpcClient, getOpenedFiles: () => getOpenedFiles, getOpenedFilesConfig: () => getOpenedFilesConfig, getPinnedFiles: () => getPinnedFiles, getPinnedFilesConfig: () => getPinnedFilesConfig, notify: () => notify, notifyConfig: () => notifyConfig, openFile: () => openFile, openFileConfig: () => openFileConfig, openFiles: () => openFiles, openFilesConfig: () => openFilesConfig, pinFiles: () => pinFiles, pinFilesConfig: () => pinFilesConfig, promptInput: () => promptInput, promptInputConfig: () => promptInputConfig, promptMultiSelect: () => promptMultiSelect, promptMultiSelectConfig: () => promptMultiSelectConfig, promptSelect: () => promptSelect, promptSelectConfig: () => promptSelectConfig, reforge: () => reforge_bundle_exports, toolFactory: () => toolFactory, unpinFiles: () => unpinFiles, unpinFilesConfig: () => unpinFilesConfig }); module.exports = __toCommonJS(reforge_index_exports); // src/reforge.bundle.ts var reforge_bundle_exports = {}; __export(reforge_bundle_exports, { getFocusedFile: () => getFocusedFile, getFocusedFileSelections: () => getFocusedFileSelections, getOpenedFiles: () => getOpenedFiles, getPinnedFiles: () => getPinnedFiles, notify: () => notify, openFile: () => openFile, openFiles: () => openFiles, pinFiles: () => pinFiles, promptInput: () => promptInput, promptMultiSelect: () => promptMultiSelect, promptSelect: () => promptSelect, unpinFiles: () => unpinFiles, vscode: () => vscode_lib_exports }); // src/reforge.lib.ts var import_v42 = require("zod/v4"); // src/tool.utils.ts var import_json = require("@synstack/json"); var net = __toESM(require("net"), 1); var import_pako = __toESM(require("pako"), 1); var import_v4 = require("zod/v4"); var RESPONSE_SUFFIX = "_RESPONSE"; var memoize = (fn) => { let cache = void 0; return (...args) => { if (cache === void 0) cache = { data: fn(...args) }; return cache.data; }; }; var getIpcClient = memoize(() => { return new Promise((resolve, reject) => { const port = process.env.REFORGE_IPC_PORT; if (!port) throw new Error("No IPC port provided, cannot connect to parent process"); const parsedPort = typeof port === "string" ? parseInt(port) : port; const client = net.connect(parsedPort, "localhost", () => { client.removeListener("error", reject); resolve(client); }); client.once("error", reject); }); }); var baseResponseSchema = import_v4.z.object({ type: import_v4.z.string(), id: import_v4.z.string(), status: import_v4.z.union([import_v4.z.literal("ok"), import_v4.z.literal("error")]) }); var toolFactory = (toolConfig) => { const responseName = `${toolConfig.name}${RESPONSE_SUFFIX}`; const responseSchema = import_v4.z.discriminatedUnion("status", [ import_v4.z.object({ status: import_v4.z.literal("ok"), type: import_v4.z.literal(responseName), id: import_v4.z.string(), data: toolConfig.responseSchema }), import_v4.z.object({ status: import_v4.z.literal("error"), type: import_v4.z.literal(responseName), id: import_v4.z.string(), data: import_v4.z.string() }) ]); const exec = async (data) => { const validatedData = toolConfig.requestSchema ? toolConfig.requestSchema.parse(data) : void 0; const client = await getIpcClient(); const id = crypto.randomUUID(); return new Promise((resolve, reject) => { const errorHandler = (error) => { client.removeListener("error", errorHandler); client.removeListener("data", responseHandler); reject(error); }; const responseHandler = (response) => { const resData = import_json.json.deserialize( import_pako.default.inflate(response, { to: "string" }) ); const baseResponse = baseResponseSchema.parse(resData); if (baseResponse.type === responseName && baseResponse.id === id) { const parsedResponse = responseSchema.parse(resData); client.removeListener("error", errorHandler); client.removeListener("data", responseHandler); if (parsedResponse.status === "ok") resolve(parsedResponse.data); else reject(new Error(parsedResponse.data)); } }; client.once("error", errorHandler); client.on("data", responseHandler); client.write( import_pako.default.deflate( import_json.json.serialize({ type: toolConfig.name, id, data: validatedData }) ) ); }); }; return exec; }; // src/reforge.lib.ts var getFocusedFileConfig = { name: "GET_FOCUSED_FILE", requestSchema: null, responseSchema: import_v42.z.string().nullable() }; var getFocusedFile = toolFactory(getFocusedFileConfig); var getOpenedFilesConfig = { name: "GET_OPENED_FILES", requestSchema: null, responseSchema: import_v42.z.array(import_v42.z.string()) }; var getOpenedFiles = toolFactory(getOpenedFilesConfig); var promptSelectConfig = { name: "PROMPT_SELECT", requestSchema: import_v42.z.object({ /** * The title of the prompt */ title: import_v42.z.string().optional(), /** * The options to display in the prompt */ options: import_v42.z.array(import_v42.z.string()), /** * The placeholder text to display in the prompt */ placeHolder: import_v42.z.string().optional() }), responseSchema: import_v42.z.string().nullable() }; var promptSelect = toolFactory(promptSelectConfig); var promptInputConfig = { name: "PROMPT_INPUT", requestSchema: import_v42.z.object({ /** * The title of the prompt */ title: import_v42.z.string().optional(), /** * The prompt to display in the prompt */ prompt: import_v42.z.string().optional(), /** * The placeholder text to display in the prompt */ placeHolder: import_v42.z.string().optional(), /** * The default input value */ defaultValue: import_v42.z.string().optional(), /** * Whether the input should be a password and masked */ isPassword: import_v42.z.boolean().optional().default(false) }), responseSchema: import_v42.z.string().nullable() }; var promptInput = toolFactory(promptInputConfig); var promptMultiSelectConfig = { name: "PROMPT_MULTI_SELECT", requestSchema: import_v42.z.object({ /** * The title of the prompt */ title: import_v42.z.string().optional(), /** * The options to display in the prompt */ options: import_v42.z.array(import_v42.z.string()), /** * The placeholder text to display in the prompt */ placeHolder: import_v42.z.string().optional() }), responseSchema: import_v42.z.array(import_v42.z.string()) }; var promptMultiSelect = toolFactory(promptMultiSelectConfig); var notifyConfig = { name: "NOTIFY", requestSchema: import_v42.z.object({ /** * The title of the notification */ title: import_v42.z.string().optional(), /** * The message to display in the notification */ message: import_v42.z.string(), /** * The type of notification * @default info * @argument info - Informational notification * @argument warning - Warning notification * @argument error - Error notification */ type: import_v42.z.enum(["info", "warning", "error"]).optional().default("info"), /** * Buttons values to display in the notification */ buttons: import_v42.z.array(import_v42.z.string()).optional() }), responseSchema: import_v42.z.string().nullable() }; var notify = toolFactory(notifyConfig); var openFileRequest = import_v42.z.object({ /** * @default false * Whether to force the file to open even if it is already open */ force: import_v42.z.boolean().default(false), /** * Whether to preview the file in the editor * @default false * @warning Check if the file type is supported by the editor */ preview: import_v42.z.boolean().optional().default(false), /** * The column to open the file in * @default active * @argument active - Open the file in the active column * @argument beside - Open the file beside the active column * @argument N - Open the file in the Nth column */ column: import_v42.z.union([import_v42.z.enum(["active", "beside"]), import_v42.z.number().min(1).max(9)]).optional() }).default({ force: false, preview: false, column: "active" }); var openFileResponse = import_v42.z.object({ /** * Absolute path to the file */ path: import_v42.z.string(), /** * Whether the file is already open in the editor */ isAlreadyOpened: import_v42.z.boolean() }); var openFileConfig = { name: "OPEN_FILE", requestSchema: import_v42.z.object({ /** * Absolute path to the file */ path: import_v42.z.string(), config: openFileRequest }), responseSchema: openFileResponse }; var openFile = toolFactory(openFileConfig); var openFilesConfig = { name: "OPEN_FILES", requestSchema: import_v42.z.object({ /** * Array of absolute paths to the files to open */ paths: import_v42.z.array(import_v42.z.string()), config: openFileRequest }), /** * Array of absolute paths to the files & whether they were already open in the editor */ responseSchema: import_v42.z.array(openFileResponse) }; var openFiles = toolFactory(openFilesConfig); var selectionPositionSchema = import_v42.z.object({ /** * The position in the whole file */ character: import_v42.z.number(), /** * The line number of the position */ line: import_v42.z.number(), /** * The character position within the line */ lineCharacter: import_v42.z.number() }); var getFocusedFileSelectionsConfig = { name: "GET_FOCUSED_FILE_SELECTION", requestSchema: null, responseSchema: import_v42.z.object({ /** * Absolute path to the file */ path: import_v42.z.string(), /** * Array of active selections in the file */ selections: import_v42.z.array( import_v42.z.object({ /** * The starting character position of the selection in the file */ start: selectionPositionSchema, /** * The ending character position of the selection in the file */ end: selectionPositionSchema, /** * The string content of the selection */ content: import_v42.z.string(), /** * The length of the selection */ length: import_v42.z.number() }) ) }).nullable() }; var getFocusedFileSelections = toolFactory( getFocusedFileSelectionsConfig ); var getPinnedFilesConfig = { name: "GET_PINNED_FILES", requestSchema: null, responseSchema: import_v42.z.array(import_v42.z.string()) }; var getPinnedFiles = toolFactory(getPinnedFilesConfig); var pinFilesConfig = { name: "PIN_FILES", requestSchema: import_v42.z.object({ paths: import_v42.z.array(import_v42.z.string()) }), responseSchema: import_v42.z.array(import_v42.z.string()) }; var pinFiles = toolFactory(pinFilesConfig); var unpinFilesConfig = { name: "UNPIN_FILES", requestSchema: import_v42.z.object({ paths: import_v42.z.array(import_v42.z.string()) }), responseSchema: import_v42.z.array(import_v42.z.string()) }; var unpinFiles = toolFactory(unpinFilesConfig); // src/vscode.lib.ts var vscode_lib_exports = {}; __export(vscode_lib_exports, { VscodeSymbolKind: () => VscodeSymbolKind, VscodeSymbolTag: () => VscodeSymbolTag, callHierarchyItemSchema: () => callHierarchyItemSchema, executeCommand: () => executeCommand, executeCommandConfig: () => executeCommandConfig, positionSchema: () => positionSchema, rangeSchema: () => rangeSchema }); var import_v43 = require("zod/v4"); var VscodeSymbolKind = { File: 0, Module: 1, Namespace: 2, Package: 3, Class: 4, Method: 5, Property: 6, Field: 7, Constructor: 8, Enum: 9, Interface: 10, Function: 11, Variable: 12, Constant: 13, String: 14, Number: 15, Boolean: 16, Array: 17, Object: 18, Key: 19, Null: 20, EnumMember: 21, Struct: 22, Event: 23, Operator: 24, TypeParameter: 25 }; var VscodeSymbolTag = { Deprecated: 1 }; var positionSchema = import_v43.z.object({ /** Zero-based line number */ line: import_v43.z.number().int().min(0), /** Zero-based character offset on the line */ character: import_v43.z.number().int().min(0) }); var rangeSchema = import_v43.z.object({ /** The start position of the range */ start: positionSchema, /** The end position of the range */ end: positionSchema }); var callHierarchyItemSchema = import_v43.z.object({ /** The symbol kind of the item */ kind: import_v43.z.number().int().min(0).max(25), /** The name of the item */ name: import_v43.z.string(), /** Additional details about the item */ detail: import_v43.z.string(), /** The URI of the document containing the item */ uri: import_v43.z.string(), /** Optional tags associated with the item */ tags: import_v43.z.array(import_v43.z.number().int()).optional(), /** The full range of the item */ range: rangeSchema, /** The range that should be selected when navigating to the item */ selectionRange: rangeSchema }); var executeCommandConfig = { name: "EXECUTE_COMMAND", requestSchema: import_v43.z.object({ /** The vscode command to execute */ command: import_v43.z.string(), /** List of args to be passed to the command */ args: import_v43.z.array( import_v43.z.discriminatedUnion("type", [ import_v43.z.object({ type: import_v43.z.literal("path"), value: import_v43.z.string() }), import_v43.z.object({ type: import_v43.z.literal("Uri"), value: import_v43.z.string().describe("Absolute path to the file") }), import_v43.z.object({ type: import_v43.z.literal("Range"), value: rangeSchema }), import_v43.z.object({ type: import_v43.z.literal("Position"), value: positionSchema }), import_v43.z.object({ type: import_v43.z.literal("CallHierarchyItem"), value: callHierarchyItemSchema }), import_v43.z.object({ type: import_v43.z.literal("primitive"), value: import_v43.z.union([ import_v43.z.string(), import_v43.z.number(), import_v43.z.boolean(), import_v43.z.record(import_v43.z.string(), import_v43.z.any()), import_v43.z.array(import_v43.z.any()) ]) }) ]) ).optional().default([]) }), responseSchema: import_v43.z.any().optional() }; var executeCommand = toolFactory(executeCommandConfig); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { RESPONSE_SUFFIX, baseResponseSchema, getFocusedFile, getFocusedFileConfig, getFocusedFileSelections, getFocusedFileSelectionsConfig, getIpcClient, getOpenedFiles, getOpenedFilesConfig, getPinnedFiles, getPinnedFilesConfig, notify, notifyConfig, openFile, openFileConfig, openFiles, openFilesConfig, pinFiles, pinFilesConfig, promptInput, promptInputConfig, promptMultiSelect, promptMultiSelectConfig, promptSelect, promptSelectConfig, reforge, toolFactory, unpinFiles, unpinFilesConfig }); //# sourceMappingURL=reforge.index.cjs.map