@synstack/reforge
Version:
Runtime tools for interactive DevX with the ReForge IDE extension
203 lines (201 loc) • 5.62 kB
JavaScript
// 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