UNPKG

@synstack/reforge

Version:

Runtime tools for interactive DevX with the ReForge IDE extension

1 lines 12.8 kB
{"version":3,"sources":["../src/vscode.index.ts","../src/vscode.lib.ts","../src/tool.utils.ts"],"sourcesContent":["export * from \"./vscode.lib.ts\";\n","import { z } from \"zod/v4\";\nimport { toolFactory } from \"./tool.utils.ts\";\n\n/**\n * Enumeration of VSCode symbol kinds.\n * These values represent different types of symbols that can be found in code.\n */\nexport const VscodeSymbolKind = {\n File: 0,\n Module: 1,\n Namespace: 2,\n Package: 3,\n Class: 4,\n Method: 5,\n Property: 6,\n Field: 7,\n Constructor: 8,\n Enum: 9,\n Interface: 10,\n Function: 11,\n Variable: 12,\n Constant: 13,\n String: 14,\n Number: 15,\n Boolean: 16,\n Array: 17,\n Object: 18,\n Key: 19,\n Null: 20,\n EnumMember: 21,\n Struct: 22,\n Event: 23,\n Operator: 24,\n TypeParameter: 25,\n} as const;\n\n/**\n * Enumeration of VSCode symbol tags.\n * These values represent additional metadata that can be attached to symbols.\n */\nexport const VscodeSymbolTag = {\n Deprecated: 1,\n} as const;\n\n/**\n * Schema for a position in a text document.\n */\nexport const positionSchema = z.object({\n /** Zero-based line number */\n line: z.number().int().min(0),\n /** Zero-based character offset on the line */\n character: z.number().int().min(0),\n});\n\n/** Type representing a position in a text document */\nexport type Position = z.output<typeof positionSchema>;\n\n/**\n * Schema for a range in a text document.\n */\nexport const rangeSchema = z.object({\n /** The start position of the range */\n start: positionSchema,\n /** The end position of the range */\n end: positionSchema,\n});\n\n/** Type representing a range in a text document */\nexport type Range = z.output<typeof rangeSchema>;\n\n/**\n * Schema for a call hierarchy item.\n * Represents a programming construct that can be part of a call hierarchy.\n */\nexport const callHierarchyItemSchema = z.object({\n /** The symbol kind of the item */\n kind: z.number().int().min(0).max(25),\n /** The name of the item */\n name: z.string(),\n /** Additional details about the item */\n detail: z.string(),\n /** The URI of the document containing the item */\n uri: z.string(),\n /** Optional tags associated with the item */\n tags: z.array(z.number().int()).optional(),\n /** The full range of the item */\n range: rangeSchema,\n /** The range that should be selected when navigating to the item */\n selectionRange: rangeSchema,\n});\n\n/** Type representing a call hierarchy item */\nexport type CallHierarchyItem = z.output<typeof callHierarchyItemSchema>;\n\n/**\n * Configuration for the executeCommand tool.\n * Defines the schema for executing VSCode commands.\n */\nexport const executeCommandConfig = {\n name: \"EXECUTE_COMMAND\",\n requestSchema: z.object({\n /** The vscode command to execute */\n command: z.string(),\n /** List of args to be passed to the command */\n args: z\n .array(\n z.discriminatedUnion(\"type\", [\n z.object({\n type: z.literal(\"path\"),\n value: z.string(),\n }),\n z.object({\n type: z.literal(\"Uri\"),\n value: z.string().describe(\"Absolute path to the file\"),\n }),\n z.object({\n type: z.literal(\"Range\"),\n value: rangeSchema,\n }),\n z.object({\n type: z.literal(\"Position\"),\n value: positionSchema,\n }),\n z.object({\n type: z.literal(\"CallHierarchyItem\"),\n value: callHierarchyItemSchema,\n }),\n z.object({\n type: z.literal(\"primitive\"),\n value: z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.record(z.string(), z.any()),\n z.array(z.any()),\n ]),\n }),\n ]),\n )\n .optional()\n .default([]),\n }),\n responseSchema: z.any().optional(),\n};\n\n/**\n * Executes a command in the VSCode editor.\n * Allows calling bundled VSCode commands as well as commands from other extensions.\n *\n * @template OUTPUT - The expected output type of the command\n * @param {z.input<typeof executeCommandConfig.requestSchema>} args - The command arguments\n * @returns {Promise<OUTPUT>} A promise that resolves with the command's output\n */\nexport const executeCommand = toolFactory(executeCommandConfig) as <\n OUTPUT = any,\n>(\n args: z.input<typeof executeCommandConfig.requestSchema>,\n) => Promise<OUTPUT>;\n","import { json } from \"@synstack/json\";\nimport * as net from \"net\";\nimport pako from \"pako\";\nimport { z } from \"zod/v4\";\n\nexport const RESPONSE_SUFFIX = \"_RESPONSE\";\n\nconst memoize = <ARGS extends Array<any>, VALUE>(\n fn: (...args: ARGS) => VALUE,\n) => {\n let cache: { data: VALUE } | undefined = undefined;\n return (...args: ARGS) => {\n if (cache === undefined) cache = { data: fn(...args) };\n return cache.data;\n };\n};\n\nexport const getIpcClient = memoize(() => {\n return new Promise<net.Socket>((resolve, reject) => {\n const port = process.env.REFORGE_IPC_PORT;\n\n if (!port)\n throw new Error(\"No IPC port provided, cannot connect to parent process\");\n\n const parsedPort = typeof port === \"string\" ? parseInt(port) : port;\n\n const client = net.connect(parsedPort, \"localhost\", () => {\n client.removeListener(\"error\", reject);\n resolve(client);\n });\n\n client.once(\"error\", reject);\n });\n});\n\nexport interface ToolConfig<\n NAME extends string,\n REQUEST_SCHEMA extends z.ZodType | null,\n RESPONSE_SCHEMA extends z.ZodType = z.ZodAny,\n> {\n name: NAME;\n requestSchema: REQUEST_SCHEMA;\n responseSchema: RESPONSE_SCHEMA;\n}\n\nexport type ToolFn<\n REQUEST_SCHEMA extends z.ZodType | null,\n RESPONSE_SCHEMA extends z.ZodType = z.ZodTypeAny,\n> = REQUEST_SCHEMA extends z.ZodType\n ? (data: z.input<REQUEST_SCHEMA>) => Promise<z.output<RESPONSE_SCHEMA>>\n : () => Promise<z.output<RESPONSE_SCHEMA>>;\n\nexport const baseResponseSchema = z.object({\n type: z.string(),\n id: z.string(),\n status: z.union([z.literal(\"ok\"), z.literal(\"error\")]),\n});\n\nexport const toolFactory = <\n NAME extends string,\n REQUEST_SCHEMA extends z.ZodType | null,\n RESPONSE_SCHEMA extends z.ZodType = z.ZodAny,\n>(\n toolConfig: ToolConfig<NAME, REQUEST_SCHEMA, RESPONSE_SCHEMA>,\n): ToolFn<REQUEST_SCHEMA, RESPONSE_SCHEMA> => {\n const responseName = `${toolConfig.name}${RESPONSE_SUFFIX}` as const;\n const responseSchema = z.discriminatedUnion(\"status\", [\n z.object({\n status: z.literal(\"ok\"),\n type: z.literal(responseName),\n id: z.string(),\n data: toolConfig.responseSchema,\n }),\n z.object({\n status: z.literal(\"error\"),\n type: z.literal(responseName),\n id: z.string(),\n data: z.string(),\n }),\n ]);\n const exec = async (data: unknown) => {\n const validatedData = toolConfig.requestSchema\n ? toolConfig.requestSchema.parse(data)\n : undefined;\n const client = await getIpcClient();\n const id = crypto.randomUUID();\n return new Promise<z.output<RESPONSE_SCHEMA>>((resolve, reject) => {\n const errorHandler = (error: Error) => {\n client.removeListener(\"error\", errorHandler);\n client.removeListener(\"data\", responseHandler);\n reject(error);\n };\n\n const responseHandler = (response: Uint8Array) => {\n const resData = json.deserialize(\n pako.inflate(response, { to: \"string\" }),\n );\n const baseResponse = baseResponseSchema.parse(resData);\n if (baseResponse.type === responseName && baseResponse.id === id) {\n const parsedResponse = responseSchema.parse(resData);\n client.removeListener(\"error\", errorHandler);\n client.removeListener(\"data\", responseHandler);\n // @ts-expect-error - TODO: fix this\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n if (parsedResponse.status === \"ok\") resolve(parsedResponse.data);\n // @ts-expect-error - TODO: fix this\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n else reject(new Error(parsedResponse.data));\n }\n };\n\n client.once(\"error\", errorHandler);\n client.on(\"data\", responseHandler);\n client.write(\n pako.deflate(\n json.serialize({\n type: toolConfig.name,\n id,\n data: validatedData,\n }),\n ),\n );\n });\n };\n\n return exec as ToolFn<REQUEST_SCHEMA, RESPONSE_SCHEMA>;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,aAAkB;;;ACAlB,kBAAqB;AACrB,UAAqB;AACrB,kBAAiB;AACjB,gBAAkB;AAEX,IAAM,kBAAkB;AAE/B,IAAM,UAAU,CACd,OACG;AACH,MAAI,QAAqC;AACzC,SAAO,IAAI,SAAe;AACxB,QAAI,UAAU,OAAW,SAAQ,EAAE,MAAM,GAAG,GAAG,IAAI,EAAE;AACrD,WAAO,MAAM;AAAA,EACf;AACF;AAEO,IAAM,eAAe,QAAQ,MAAM;AACxC,SAAO,IAAI,QAAoB,CAAC,SAAS,WAAW;AAClD,UAAM,OAAO,QAAQ,IAAI;AAEzB,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,wDAAwD;AAE1E,UAAM,aAAa,OAAO,SAAS,WAAW,SAAS,IAAI,IAAI;AAE/D,UAAM,SAAa,YAAQ,YAAY,aAAa,MAAM;AACxD,aAAO,eAAe,SAAS,MAAM;AACrC,cAAQ,MAAM;AAAA,IAChB,CAAC;AAED,WAAO,KAAK,SAAS,MAAM;AAAA,EAC7B,CAAC;AACH,CAAC;AAmBM,IAAM,qBAAqB,YAAE,OAAO;AAAA,EACzC,MAAM,YAAE,OAAO;AAAA,EACf,IAAI,YAAE,OAAO;AAAA,EACb,QAAQ,YAAE,MAAM,CAAC,YAAE,QAAQ,IAAI,GAAG,YAAE,QAAQ,OAAO,CAAC,CAAC;AACvD,CAAC;AAEM,IAAM,cAAc,CAKzB,eAC4C;AAC5C,QAAM,eAAe,GAAG,WAAW,IAAI,GAAG,eAAe;AACzD,QAAM,iBAAiB,YAAE,mBAAmB,UAAU;AAAA,IACpD,YAAE,OAAO;AAAA,MACP,QAAQ,YAAE,QAAQ,IAAI;AAAA,MACtB,MAAM,YAAE,QAAQ,YAAY;AAAA,MAC5B,IAAI,YAAE,OAAO;AAAA,MACb,MAAM,WAAW;AAAA,IACnB,CAAC;AAAA,IACD,YAAE,OAAO;AAAA,MACP,QAAQ,YAAE,QAAQ,OAAO;AAAA,MACzB,MAAM,YAAE,QAAQ,YAAY;AAAA,MAC5B,IAAI,YAAE,OAAO;AAAA,MACb,MAAM,YAAE,OAAO;AAAA,IACjB,CAAC;AAAA,EACH,CAAC;AACD,QAAM,OAAO,OAAO,SAAkB;AACpC,UAAM,gBAAgB,WAAW,gBAC7B,WAAW,cAAc,MAAM,IAAI,IACnC;AACJ,UAAM,SAAS,MAAM,aAAa;AAClC,UAAM,KAAK,OAAO,WAAW;AAC7B,WAAO,IAAI,QAAmC,CAAC,SAAS,WAAW;AACjE,YAAM,eAAe,CAAC,UAAiB;AACrC,eAAO,eAAe,SAAS,YAAY;AAC3C,eAAO,eAAe,QAAQ,eAAe;AAC7C,eAAO,KAAK;AAAA,MACd;AAEA,YAAM,kBAAkB,CAAC,aAAyB;AAChD,cAAM,UAAU,iBAAK;AAAA,UACnB,YAAAC,QAAK,QAAQ,UAAU,EAAE,IAAI,SAAS,CAAC;AAAA,QACzC;AACA,cAAM,eAAe,mBAAmB,MAAM,OAAO;AACrD,YAAI,aAAa,SAAS,gBAAgB,aAAa,OAAO,IAAI;AAChE,gBAAM,iBAAiB,eAAe,MAAM,OAAO;AACnD,iBAAO,eAAe,SAAS,YAAY;AAC3C,iBAAO,eAAe,QAAQ,eAAe;AAG7C,cAAI,eAAe,WAAW,KAAM,SAAQ,eAAe,IAAI;AAAA,cAG1D,QAAO,IAAI,MAAM,eAAe,IAAI,CAAC;AAAA,QAC5C;AAAA,MACF;AAEA,aAAO,KAAK,SAAS,YAAY;AACjC,aAAO,GAAG,QAAQ,eAAe;AACjC,aAAO;AAAA,QACL,YAAAA,QAAK;AAAA,UACH,iBAAK,UAAU;AAAA,YACb,MAAM,WAAW;AAAA,YACjB;AAAA,YACA,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ADvHO,IAAM,mBAAmB;AAAA,EAC9B,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,aAAa;AAAA,EACb,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,UAAU;AAAA,EACV,eAAe;AACjB;AAMO,IAAM,kBAAkB;AAAA,EAC7B,YAAY;AACd;AAKO,IAAM,iBAAiB,aAAE,OAAO;AAAA;AAAA,EAErC,MAAM,aAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC;AAAA;AAAA,EAE5B,WAAW,aAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC;AACnC,CAAC;AAQM,IAAM,cAAc,aAAE,OAAO;AAAA;AAAA,EAElC,OAAO;AAAA;AAAA,EAEP,KAAK;AACP,CAAC;AASM,IAAM,0BAA0B,aAAE,OAAO;AAAA;AAAA,EAE9C,MAAM,aAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA;AAAA,EAEpC,MAAM,aAAE,OAAO;AAAA;AAAA,EAEf,QAAQ,aAAE,OAAO;AAAA;AAAA,EAEjB,KAAK,aAAE,OAAO;AAAA;AAAA,EAEd,MAAM,aAAE,MAAM,aAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA;AAAA,EAEzC,OAAO;AAAA;AAAA,EAEP,gBAAgB;AAClB,CAAC;AASM,IAAM,uBAAuB;AAAA,EAClC,MAAM;AAAA,EACN,eAAe,aAAE,OAAO;AAAA;AAAA,IAEtB,SAAS,aAAE,OAAO;AAAA;AAAA,IAElB,MAAM,aACH;AAAA,MACC,aAAE,mBAAmB,QAAQ;AAAA,QAC3B,aAAE,OAAO;AAAA,UACP,MAAM,aAAE,QAAQ,MAAM;AAAA,UACtB,OAAO,aAAE,OAAO;AAAA,QAClB,CAAC;AAAA,QACD,aAAE,OAAO;AAAA,UACP,MAAM,aAAE,QAAQ,KAAK;AAAA,UACrB,OAAO,aAAE,OAAO,EAAE,SAAS,2BAA2B;AAAA,QACxD,CAAC;AAAA,QACD,aAAE,OAAO;AAAA,UACP,MAAM,aAAE,QAAQ,OAAO;AAAA,UACvB,OAAO;AAAA,QACT,CAAC;AAAA,QACD,aAAE,OAAO;AAAA,UACP,MAAM,aAAE,QAAQ,UAAU;AAAA,UAC1B,OAAO;AAAA,QACT,CAAC;AAAA,QACD,aAAE,OAAO;AAAA,UACP,MAAM,aAAE,QAAQ,mBAAmB;AAAA,UACnC,OAAO;AAAA,QACT,CAAC;AAAA,QACD,aAAE,OAAO;AAAA,UACP,MAAM,aAAE,QAAQ,WAAW;AAAA,UAC3B,OAAO,aAAE,MAAM;AAAA,YACb,aAAE,OAAO;AAAA,YACT,aAAE,OAAO;AAAA,YACT,aAAE,QAAQ;AAAA,YACV,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,IAAI,CAAC;AAAA,YAC5B,aAAE,MAAM,aAAE,IAAI,CAAC;AAAA,UACjB,CAAC;AAAA,QACH,CAAC;AAAA,MACH,CAAC;AAAA,IACH,EACC,SAAS,EACT,QAAQ,CAAC,CAAC;AAAA,EACf,CAAC;AAAA,EACD,gBAAgB,aAAE,IAAI,EAAE,SAAS;AACnC;AAUO,IAAM,iBAAiB,YAAY,oBAAoB;","names":["import_v4","pako"]}