@synstack/reforge
Version:
Runtime tools for interactive DevX with the ReForge IDE extension
500 lines (495 loc) • 13.3 kB
JavaScript
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// 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
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/reforge.lib.ts
var getFocusedFileConfig = {
name: "GET_FOCUSED_FILE",
requestSchema: null,
responseSchema: z2.string().nullable()
};
var getFocusedFile = toolFactory(getFocusedFileConfig);
var getOpenedFilesConfig = {
name: "GET_OPENED_FILES",
requestSchema: null,
responseSchema: z2.array(z2.string())
};
var getOpenedFiles = toolFactory(getOpenedFilesConfig);
var promptSelectConfig = {
name: "PROMPT_SELECT",
requestSchema: z2.object({
/**
* The title of the prompt
*/
title: z2.string().optional(),
/**
* The options to display in the prompt
*/
options: z2.array(z2.string()),
/**
* The placeholder text to display in the prompt
*/
placeHolder: z2.string().optional()
}),
responseSchema: z2.string().nullable()
};
var promptSelect = toolFactory(promptSelectConfig);
var promptInputConfig = {
name: "PROMPT_INPUT",
requestSchema: z2.object({
/**
* The title of the prompt
*/
title: z2.string().optional(),
/**
* The prompt to display in the prompt
*/
prompt: z2.string().optional(),
/**
* The placeholder text to display in the prompt
*/
placeHolder: z2.string().optional(),
/**
* The default input value
*/
defaultValue: z2.string().optional(),
/**
* Whether the input should be a password and masked
*/
isPassword: z2.boolean().optional().default(false)
}),
responseSchema: z2.string().nullable()
};
var promptInput = toolFactory(promptInputConfig);
var promptMultiSelectConfig = {
name: "PROMPT_MULTI_SELECT",
requestSchema: z2.object({
/**
* The title of the prompt
*/
title: z2.string().optional(),
/**
* The options to display in the prompt
*/
options: z2.array(z2.string()),
/**
* The placeholder text to display in the prompt
*/
placeHolder: z2.string().optional()
}),
responseSchema: z2.array(z2.string())
};
var promptMultiSelect = toolFactory(promptMultiSelectConfig);
var notifyConfig = {
name: "NOTIFY",
requestSchema: z2.object({
/**
* The title of the notification
*/
title: z2.string().optional(),
/**
* The message to display in the notification
*/
message: z2.string(),
/**
* The type of notification
* @default info
* @argument info - Informational notification
* @argument warning - Warning notification
* @argument error - Error notification
*/
type: z2.enum(["info", "warning", "error"]).optional().default("info"),
/**
* Buttons values to display in the notification
*/
buttons: z2.array(z2.string()).optional()
}),
responseSchema: z2.string().nullable()
};
var notify = toolFactory(notifyConfig);
var openFileRequest = z2.object({
/**
* @default false
* Whether to force the file to open even if it is already open
*/
force: z2.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: z2.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: z2.union([z2.enum(["active", "beside"]), z2.number().min(1).max(9)]).optional()
}).default({
force: false,
preview: false,
column: "active"
});
var openFileResponse = z2.object({
/**
* Absolute path to the file
*/
path: z2.string(),
/**
* Whether the file is already open in the editor
*/
isAlreadyOpened: z2.boolean()
});
var openFileConfig = {
name: "OPEN_FILE",
requestSchema: z2.object({
/**
* Absolute path to the file
*/
path: z2.string(),
config: openFileRequest
}),
responseSchema: openFileResponse
};
var openFile = toolFactory(openFileConfig);
var openFilesConfig = {
name: "OPEN_FILES",
requestSchema: z2.object({
/**
* Array of absolute paths to the files to open
*/
paths: z2.array(z2.string()),
config: openFileRequest
}),
/**
* Array of absolute paths to the files & whether they were already open in the editor
*/
responseSchema: z2.array(openFileResponse)
};
var openFiles = toolFactory(openFilesConfig);
var selectionPositionSchema = z2.object({
/**
* The position in the whole file
*/
character: z2.number(),
/**
* The line number of the position
*/
line: z2.number(),
/**
* The character position within the line
*/
lineCharacter: z2.number()
});
var getFocusedFileSelectionsConfig = {
name: "GET_FOCUSED_FILE_SELECTION",
requestSchema: null,
responseSchema: z2.object({
/**
* Absolute path to the file
*/
path: z2.string(),
/**
* Array of active selections in the file
*/
selections: z2.array(
z2.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: z2.string(),
/**
* The length of the selection
*/
length: z2.number()
})
)
}).nullable()
};
var getFocusedFileSelections = toolFactory(
getFocusedFileSelectionsConfig
);
var getPinnedFilesConfig = {
name: "GET_PINNED_FILES",
requestSchema: null,
responseSchema: z2.array(z2.string())
};
var getPinnedFiles = toolFactory(getPinnedFilesConfig);
var pinFilesConfig = {
name: "PIN_FILES",
requestSchema: z2.object({
paths: z2.array(z2.string())
}),
responseSchema: z2.array(z2.string())
};
var pinFiles = toolFactory(pinFilesConfig);
var unpinFilesConfig = {
name: "UNPIN_FILES",
requestSchema: z2.object({
paths: z2.array(z2.string())
}),
responseSchema: z2.array(z2.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
});
import { z as z3 } from "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 = z3.object({
/** Zero-based line number */
line: z3.number().int().min(0),
/** Zero-based character offset on the line */
character: z3.number().int().min(0)
});
var rangeSchema = z3.object({
/** The start position of the range */
start: positionSchema,
/** The end position of the range */
end: positionSchema
});
var callHierarchyItemSchema = z3.object({
/** The symbol kind of the item */
kind: z3.number().int().min(0).max(25),
/** The name of the item */
name: z3.string(),
/** Additional details about the item */
detail: z3.string(),
/** The URI of the document containing the item */
uri: z3.string(),
/** Optional tags associated with the item */
tags: z3.array(z3.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: z3.object({
/** The vscode command to execute */
command: z3.string(),
/** List of args to be passed to the command */
args: z3.array(
z3.discriminatedUnion("type", [
z3.object({
type: z3.literal("path"),
value: z3.string()
}),
z3.object({
type: z3.literal("Uri"),
value: z3.string().describe("Absolute path to the file")
}),
z3.object({
type: z3.literal("Range"),
value: rangeSchema
}),
z3.object({
type: z3.literal("Position"),
value: positionSchema
}),
z3.object({
type: z3.literal("CallHierarchyItem"),
value: callHierarchyItemSchema
}),
z3.object({
type: z3.literal("primitive"),
value: z3.union([
z3.string(),
z3.number(),
z3.boolean(),
z3.record(z3.string(), z3.any()),
z3.array(z3.any())
])
})
])
).optional().default([])
}),
responseSchema: z3.any().optional()
};
var executeCommand = toolFactory(executeCommandConfig);
export {
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_bundle_exports as reforge,
toolFactory,
unpinFiles,
unpinFilesConfig
};
//# sourceMappingURL=reforge.index.js.map