UNPKG

@synstack/reforge

Version:

Runtime tools for interactive DevX with the ReForge IDE extension

203 lines (201 loc) 5.62 kB
// src/vscode.lib.ts import { z as z2 } from "zod/v4"; // src/tool.utils.ts import { json } from "@synstack/json"; import * as net from "net"; import pako from "pako"; import { z } from "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 = z.object({ type: z.string(), id: z.string(), status: z.union([z.literal("ok"), z.literal("error")]) }); var toolFactory = (toolConfig) => { const responseName = `${toolConfig.name}${RESPONSE_SUFFIX}`; const responseSchema = z.discriminatedUnion("status", [ z.object({ status: z.literal("ok"), type: z.literal(responseName), id: z.string(), data: toolConfig.responseSchema }), z.object({ status: z.literal("error"), type: z.literal(responseName), id: z.string(), data: 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 = json.deserialize( pako.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( pako.deflate( json.serialize({ type: toolConfig.name, id, data: validatedData }) ) ); }); }; return exec; }; // src/vscode.lib.ts 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 = z2.object({ /** Zero-based line number */ line: z2.number().int().min(0), /** Zero-based character offset on the line */ character: z2.number().int().min(0) }); var rangeSchema = z2.object({ /** The start position of the range */ start: positionSchema, /** The end position of the range */ end: positionSchema }); var callHierarchyItemSchema = z2.object({ /** The symbol kind of the item */ kind: z2.number().int().min(0).max(25), /** The name of the item */ name: z2.string(), /** Additional details about the item */ detail: z2.string(), /** The URI of the document containing the item */ uri: z2.string(), /** Optional tags associated with the item */ tags: z2.array(z2.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: z2.object({ /** The vscode command to execute */ command: z2.string(), /** List of args to be passed to the command */ args: z2.array( z2.discriminatedUnion("type", [ z2.object({ type: z2.literal("path"), value: z2.string() }), z2.object({ type: z2.literal("Uri"), value: z2.string().describe("Absolute path to the file") }), z2.object({ type: z2.literal("Range"), value: rangeSchema }), z2.object({ type: z2.literal("Position"), value: positionSchema }), z2.object({ type: z2.literal("CallHierarchyItem"), value: callHierarchyItemSchema }), z2.object({ type: z2.literal("primitive"), value: z2.union([ z2.string(), z2.number(), z2.boolean(), z2.record(z2.string(), z2.any()), z2.array(z2.any()) ]) }) ]) ).optional().default([]) }), responseSchema: z2.any().optional() }; var executeCommand = toolFactory(executeCommandConfig); export { VscodeSymbolKind, VscodeSymbolTag, callHierarchyItemSchema, executeCommand, executeCommandConfig, positionSchema, rangeSchema }; //# sourceMappingURL=vscode.index.js.map