mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
IPC tweaks
This commit is contained in:
parent
8b367116b1
commit
8c1a22f5dd
12 changed files with 892 additions and 354 deletions
|
|
@ -1,10 +1,12 @@
|
|||
import { IpcClient } from "../src/ipcClient"
|
||||
import { IpcClientMessageType, IpcClient } from "../src/index.js"
|
||||
|
||||
async function main(socketPath: string) {
|
||||
async function main(socketPath: string, prompt: string) {
|
||||
try {
|
||||
const startTime = Date.now()
|
||||
const client = new IpcClient(socketPath)
|
||||
|
||||
client.on("message", (data) => console.log(data))
|
||||
|
||||
while (!client.isConnected) {
|
||||
if (Date.now() - startTime > 5000) {
|
||||
throw new Error("Failed to connect to server.")
|
||||
|
|
@ -13,9 +15,10 @@ async function main(socketPath: string) {
|
|||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
}
|
||||
|
||||
client.sendMessage({ type: IpcClientMessageType.StartNewTask, data: { text: prompt } })
|
||||
|
||||
while (client.isConnected) {
|
||||
client.ping()
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000))
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
}
|
||||
|
||||
process.exit(0)
|
||||
|
|
@ -26,8 +29,8 @@ async function main(socketPath: string) {
|
|||
}
|
||||
|
||||
if (!process.argv[2]) {
|
||||
console.error("Usage: npx tsx scripts/client.ts <socketPath>")
|
||||
console.error("Usage: npx tsx scripts/client.ts <socketPath> <prompt>")
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
main(process.argv[2])
|
||||
main(process.argv[2], process.argv[3])
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
import { IpcServer } from "../src/ipcServer"
|
||||
import { ServerMessageType } from "../src/types"
|
||||
|
||||
async function main(socketPath: string) {
|
||||
try {
|
||||
const server = new IpcServer(socketPath)
|
||||
server.listen()
|
||||
console.log(`listening @ ${server.socketPath}`)
|
||||
|
||||
while (server.isListening) {
|
||||
server.broadcast({ type: ServerMessageType.Message, data: { message: "hello" } })
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
}
|
||||
|
||||
process.exit(0)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if (!process.argv[2]) {
|
||||
console.error("Usage: npx tsx scripts/client.ts <socketPath>")
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
main(process.argv[2])
|
||||
|
|
@ -1,4 +1,262 @@
|
|||
export { IpcClient } from "./ipcClient.js"
|
||||
export { IpcServer } from "./ipcServer.js"
|
||||
import EventEmitter from "node:events"
|
||||
import { Socket } from "node:net"
|
||||
import * as crypto from "node:crypto"
|
||||
|
||||
export * from "./types.js"
|
||||
import ipc from "node-ipc"
|
||||
import { z } from "zod"
|
||||
|
||||
/**
|
||||
* IpcClient
|
||||
*/
|
||||
|
||||
export type IpcClientId = string
|
||||
|
||||
export enum IpcClientMessageType {
|
||||
Message = "Message",
|
||||
StartNewTask = "StartNewTask",
|
||||
}
|
||||
|
||||
export const ipcClientMessageSchema = z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal(IpcClientMessageType.StartNewTask),
|
||||
data: z.object({
|
||||
text: z.string(),
|
||||
images: z.array(z.string()).optional(),
|
||||
}),
|
||||
}),
|
||||
])
|
||||
|
||||
export type IpcClientMessage = z.infer<typeof ipcClientMessageSchema>
|
||||
|
||||
export interface IpcClientEvents {
|
||||
connect: []
|
||||
disconnect: []
|
||||
message: [data: IpcServerMessage]
|
||||
}
|
||||
|
||||
export class IpcClient extends EventEmitter<IpcClientEvents> {
|
||||
private readonly _socketPath: string
|
||||
private readonly _log: (...args: unknown[]) => void
|
||||
|
||||
private _isConnected = false
|
||||
private _clientId?: IpcClientId
|
||||
|
||||
constructor(socketPath: string, log = console.log) {
|
||||
super()
|
||||
|
||||
this._socketPath = socketPath
|
||||
this._log = log
|
||||
|
||||
ipc.config.silent = true
|
||||
|
||||
ipc.connectTo("benchmarkServer", this.socketPath, () => {
|
||||
ipc.of.benchmarkServer?.on("connect", (args) => this.onConnect(args))
|
||||
ipc.of.benchmarkServer?.on("disconnect", (args) => this.onDisconnect(args))
|
||||
ipc.of.benchmarkServer?.on("message", (data) => this.onMessage(data))
|
||||
})
|
||||
}
|
||||
|
||||
private onConnect(args: unknown) {
|
||||
if (this._isConnected) {
|
||||
return
|
||||
}
|
||||
|
||||
this.log("[client#onConnect]", args)
|
||||
this._isConnected = true
|
||||
this.emit("connect")
|
||||
}
|
||||
|
||||
private onDisconnect(args: unknown) {
|
||||
if (!this._isConnected) {
|
||||
return
|
||||
}
|
||||
|
||||
this.log("[client#onDisconnect]", args)
|
||||
this._isConnected = false
|
||||
this.emit("disconnect")
|
||||
}
|
||||
|
||||
private onMessage(data: unknown) {
|
||||
if (typeof data !== "object") {
|
||||
this._log("[client#onMessage] invalid data", data)
|
||||
return
|
||||
}
|
||||
|
||||
const result = ipcServerMessageSchema.safeParse(data)
|
||||
|
||||
if (!result.success) {
|
||||
this.log("[client#onMessage] invalid payload", result.error)
|
||||
return
|
||||
}
|
||||
|
||||
this.emit("message", result.data)
|
||||
}
|
||||
|
||||
private log(...args: unknown[]) {
|
||||
this._log(...args)
|
||||
}
|
||||
|
||||
public sendMessage(message: IpcClientMessage) {
|
||||
ipc.of.benchmarkServer?.emit("message", message)
|
||||
}
|
||||
|
||||
public disconnect() {
|
||||
try {
|
||||
ipc.disconnect("benchmarkServer")
|
||||
// @TODO: Should we set _disconnect here?
|
||||
} catch (error) {
|
||||
this.log("[client#disconnect] error disconnecting", error)
|
||||
}
|
||||
}
|
||||
|
||||
public get socketPath() {
|
||||
return this._socketPath
|
||||
}
|
||||
|
||||
public get clientId() {
|
||||
return this._clientId
|
||||
}
|
||||
|
||||
public get isConnected() {
|
||||
return this._isConnected
|
||||
}
|
||||
|
||||
public get isReady() {
|
||||
return this._isConnected && this._clientId !== undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* IpcServer
|
||||
*/
|
||||
|
||||
export enum IpcServerMessageType {
|
||||
Ack = "Ack",
|
||||
TaskEvent = "TaskEvent",
|
||||
}
|
||||
|
||||
export const ipcServerMessageSchema = z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal(IpcServerMessageType.Ack),
|
||||
data: z.object({ clientId: z.string() }),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal(IpcServerMessageType.TaskEvent),
|
||||
data: z.object({
|
||||
eventName: z.string(),
|
||||
data: z.unknown(),
|
||||
}),
|
||||
}),
|
||||
])
|
||||
|
||||
export type IpcServerMessage = z.infer<typeof ipcServerMessageSchema>
|
||||
|
||||
type IpcServerEvents = {
|
||||
connect: [id: IpcClientId]
|
||||
disconnect: [id: IpcClientId]
|
||||
message: [data: IpcClientMessage]
|
||||
}
|
||||
|
||||
export class IpcServer extends EventEmitter<IpcServerEvents> {
|
||||
private readonly _socketPath: string
|
||||
private readonly _log: (...args: unknown[]) => void
|
||||
private readonly _clients: Map<string, Socket>
|
||||
|
||||
private _isListening = false
|
||||
|
||||
constructor(socketPath: string, log = console.log) {
|
||||
super()
|
||||
|
||||
this._socketPath = socketPath
|
||||
this._log = log
|
||||
this._clients = new Map()
|
||||
}
|
||||
|
||||
public listen() {
|
||||
this._isListening = true
|
||||
|
||||
ipc.config.silent = true
|
||||
|
||||
ipc.serve(this.socketPath, () => {
|
||||
ipc.server.on("connect", (socket) => this.onConnect(socket))
|
||||
ipc.server.on("socket.disconnected", (socket) => this.onDisconnect(socket))
|
||||
ipc.server.on("message", (data) => this.onMessage(data))
|
||||
})
|
||||
|
||||
ipc.server.start()
|
||||
}
|
||||
|
||||
private onConnect(socket: Socket) {
|
||||
const clientId = crypto.randomBytes(6).toString("hex")
|
||||
this._clients.set(clientId, socket)
|
||||
this.log(`[server#onConnect] clientId = ${clientId}, # clients = ${this._clients.size}`)
|
||||
this.send(socket, { type: IpcServerMessageType.Ack, data: { clientId } })
|
||||
this.emit("connect", clientId)
|
||||
}
|
||||
|
||||
private onDisconnect(destroyedSocket: Socket) {
|
||||
let disconnectedClientId: IpcClientId | undefined
|
||||
|
||||
for (const [clientId, socket] of this._clients.entries()) {
|
||||
if (socket === destroyedSocket) {
|
||||
disconnectedClientId = clientId
|
||||
this._clients.delete(clientId)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
this.log(`[server#socket.disconnected] clientId = ${disconnectedClientId}, # clients = ${this._clients.size}`)
|
||||
|
||||
if (disconnectedClientId) {
|
||||
this.emit("disconnect", disconnectedClientId)
|
||||
}
|
||||
}
|
||||
|
||||
private onMessage(data: unknown) {
|
||||
if (typeof data !== "object") {
|
||||
this.log("[server#onMessage] invalid data", data)
|
||||
return
|
||||
}
|
||||
|
||||
const result = ipcClientMessageSchema.safeParse(data)
|
||||
|
||||
if (!result.success) {
|
||||
this.log("[server#onMessage] invalid payload", result.error)
|
||||
return
|
||||
}
|
||||
|
||||
const payload = result.data
|
||||
this.emit("message", payload)
|
||||
}
|
||||
|
||||
private log(...args: unknown[]) {
|
||||
this._log(...args)
|
||||
}
|
||||
|
||||
public broadcast(message: IpcServerMessage) {
|
||||
this.log("[server#broadcast] message =", message)
|
||||
ipc.server.broadcast("message", message)
|
||||
}
|
||||
|
||||
public send(client: IpcClientId | Socket, message: IpcServerMessage) {
|
||||
this.log("[server#send] message =", message)
|
||||
|
||||
if (typeof client === "string") {
|
||||
const socket = this._clients.get(client)
|
||||
|
||||
if (socket) {
|
||||
ipc.server.emit(socket, "message", message)
|
||||
}
|
||||
} else {
|
||||
ipc.server.emit(client, "message", message)
|
||||
}
|
||||
}
|
||||
|
||||
public get socketPath() {
|
||||
return this._socketPath
|
||||
}
|
||||
|
||||
public get isListening() {
|
||||
return this._isListening
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
import EventEmitter from "node:events"
|
||||
import ipc from "node-ipc"
|
||||
|
||||
import { ClientMessage, ClientMessageType, ServerMessage, ServerMessageType, serverMessageSchema } from "./types.js"
|
||||
|
||||
export interface IpcClientEvents {
|
||||
connect: []
|
||||
message: [data: ServerMessage]
|
||||
disconnect: []
|
||||
}
|
||||
|
||||
export class IpcClient extends EventEmitter<IpcClientEvents> {
|
||||
private readonly _socketPath: string
|
||||
private readonly _log: (...args: unknown[]) => void
|
||||
|
||||
private _isConnected = false
|
||||
private _clientId?: string
|
||||
|
||||
constructor(socketPath: string, log = console.log) {
|
||||
super()
|
||||
|
||||
this._socketPath = socketPath
|
||||
this._log = log
|
||||
|
||||
ipc.config.silent = true
|
||||
|
||||
ipc.connectTo("benchmarkServer", this.socketPath, () => {
|
||||
ipc.of.benchmarkServer?.on("connect", (args) => this.onConnect(args))
|
||||
ipc.of.benchmarkServer?.on("message", (data) => this.onMessage(data))
|
||||
ipc.of.benchmarkServer?.on("disconnect", (args) => this.onDisconnect(args))
|
||||
})
|
||||
}
|
||||
|
||||
private onConnect(args: unknown) {
|
||||
if (this._isConnected) {
|
||||
return
|
||||
}
|
||||
|
||||
this.log("[client#onConnect]", args)
|
||||
this._isConnected = true
|
||||
this.emit("connect")
|
||||
}
|
||||
|
||||
private onMessage(data: unknown) {
|
||||
if (typeof data !== "object") {
|
||||
this._log("[client#onMessage] invalid data", data)
|
||||
return
|
||||
}
|
||||
|
||||
const result = serverMessageSchema.safeParse(data)
|
||||
|
||||
if (!result.success) {
|
||||
this.log("[client#onMessage] invalid payload", result.error)
|
||||
return
|
||||
}
|
||||
|
||||
const payload = result.data
|
||||
|
||||
switch (payload.type) {
|
||||
case ServerMessageType.Hello:
|
||||
this.log(`[client#Hello] ${payload.data.clientId}`)
|
||||
this._clientId = payload.data.clientId
|
||||
break
|
||||
case ServerMessageType.Pong:
|
||||
this.log(`[client#Pong]`)
|
||||
break
|
||||
}
|
||||
|
||||
this.emit("message", payload)
|
||||
}
|
||||
|
||||
private onDisconnect(args: unknown) {
|
||||
if (!this._isConnected) {
|
||||
return
|
||||
}
|
||||
|
||||
this.log("[client#onDisconnect]", args)
|
||||
this._isConnected = false
|
||||
this.emit("disconnect")
|
||||
}
|
||||
|
||||
public sendMessage(message: ClientMessage) {
|
||||
ipc.of.benchmarkServer?.emit("message", message)
|
||||
}
|
||||
|
||||
private log(...args: unknown[]) {
|
||||
this._log(...args)
|
||||
}
|
||||
|
||||
public ping() {
|
||||
if (!this.isReady) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.sendMessage({ type: ClientMessageType.Ping, data: { clientId: this._clientId! } })
|
||||
return true
|
||||
}
|
||||
|
||||
public disconnect() {
|
||||
try {
|
||||
ipc.disconnect("benchmarkServer")
|
||||
// @TODO: Should we set _disconnect here?
|
||||
} catch (error) {
|
||||
this.log("[client#disconnect] error disconnecting", error)
|
||||
}
|
||||
}
|
||||
|
||||
public get socketPath() {
|
||||
return this._socketPath
|
||||
}
|
||||
|
||||
public get clientId() {
|
||||
return this._clientId
|
||||
}
|
||||
|
||||
public get isConnected() {
|
||||
return this._isConnected
|
||||
}
|
||||
|
||||
public get isReady() {
|
||||
return this._isConnected && this._clientId !== undefined
|
||||
}
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
import { Socket } from "node:net"
|
||||
import * as crypto from "node:crypto"
|
||||
import EventEmitter from "node:events"
|
||||
|
||||
import ipc from "node-ipc"
|
||||
|
||||
import { ClientMessageType, ServerMessage, ServerMessageType, clientMessageSchema } from "./types.js"
|
||||
|
||||
type IpcServerEvents = {
|
||||
client: [id: string]
|
||||
}
|
||||
|
||||
export class IpcServer extends EventEmitter<IpcServerEvents> {
|
||||
private readonly _socketPath: string
|
||||
private readonly _log: (...args: unknown[]) => void
|
||||
private readonly _clients: Map<string, Socket>
|
||||
|
||||
private _isListening = false
|
||||
|
||||
constructor(socketPath: string, log = console.log) {
|
||||
super()
|
||||
|
||||
this._socketPath = socketPath
|
||||
this._log = log
|
||||
this._clients = new Map()
|
||||
}
|
||||
|
||||
public listen() {
|
||||
this._isListening = true
|
||||
|
||||
ipc.config.silent = true
|
||||
|
||||
ipc.serve(this.socketPath, () => {
|
||||
ipc.server.on("connect", (socket) => this.onConnect(socket))
|
||||
ipc.server.on("message", (data, socket) => this.onMessage(data, socket))
|
||||
ipc.server.on("socket.disconnected", (socket) => this.onDisconnect(socket))
|
||||
})
|
||||
|
||||
ipc.server.start()
|
||||
}
|
||||
|
||||
private onConnect(socket: Socket) {
|
||||
const clientId = crypto.randomBytes(6).toString("hex")
|
||||
this._clients.set(clientId, socket)
|
||||
this.log(`[server#onConnect] clientId = ${clientId}, # clients = ${this._clients.size}`)
|
||||
this.send(socket, { type: ServerMessageType.Hello, data: { clientId } })
|
||||
this.emit("client", clientId)
|
||||
}
|
||||
|
||||
private onMessage(data: unknown, socket: Socket) {
|
||||
if (typeof data !== "object") {
|
||||
this.log("[server#onMessage] invalid data", data)
|
||||
return
|
||||
}
|
||||
|
||||
const result = clientMessageSchema.safeParse(data)
|
||||
|
||||
if (!result.success) {
|
||||
this.log("[server#onMessage] invalid payload", result.error)
|
||||
return
|
||||
}
|
||||
|
||||
const payload = result.data
|
||||
|
||||
switch (payload.type) {
|
||||
case ClientMessageType.Message:
|
||||
this.log(`[server#Message] ${payload.data.message}`)
|
||||
break
|
||||
case ClientMessageType.Ping:
|
||||
this.log(`[server#Ping]`)
|
||||
this.send(socket, { type: ServerMessageType.Pong })
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
private onDisconnect(destroyedSocket: Socket) {
|
||||
let destroyedClientId: string | undefined
|
||||
|
||||
for (const [clientId, socket] of this._clients.entries()) {
|
||||
if (socket === destroyedSocket) {
|
||||
destroyedClientId = clientId
|
||||
this._clients.delete(clientId)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
this.log(`[server#socket.disconnected] clientId = ${destroyedClientId}, # clients = ${this._clients.size}`)
|
||||
}
|
||||
|
||||
private log(...args: unknown[]) {
|
||||
this._log(...args)
|
||||
}
|
||||
|
||||
public broadcast(message: ServerMessage) {
|
||||
this.log("[server#broadcast] message =", message)
|
||||
ipc.server.broadcast("message", message)
|
||||
}
|
||||
|
||||
public send(client: string | Socket, message: ServerMessage) {
|
||||
this.log("[server#send] message =", message)
|
||||
|
||||
if (typeof client === "string") {
|
||||
const socket = this._clients.get(client)
|
||||
|
||||
if (socket) {
|
||||
ipc.server.emit(socket, "message", message)
|
||||
}
|
||||
} else {
|
||||
ipc.server.emit(client, "message", message)
|
||||
}
|
||||
}
|
||||
|
||||
public get socketPath() {
|
||||
return this._socketPath
|
||||
}
|
||||
|
||||
public get isListening() {
|
||||
return this._isListening
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
import { z } from "zod"
|
||||
|
||||
/**
|
||||
* Client
|
||||
*/
|
||||
|
||||
export enum ClientMessageType {
|
||||
Ping = "ping",
|
||||
Message = "message",
|
||||
}
|
||||
|
||||
export const clientMessageSchema = z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal(ClientMessageType.Message),
|
||||
data: z.object({
|
||||
clientId: z.string(),
|
||||
message: z.string(),
|
||||
}),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal(ClientMessageType.Ping),
|
||||
data: z.object({
|
||||
clientId: z.string(),
|
||||
}),
|
||||
}),
|
||||
])
|
||||
|
||||
export type ClientMessage = z.infer<typeof clientMessageSchema>
|
||||
|
||||
/**
|
||||
* Server
|
||||
*/
|
||||
|
||||
export enum ServerMessageType {
|
||||
Hello = "hello",
|
||||
Pong = "pong",
|
||||
Message = "message",
|
||||
Data = "data",
|
||||
}
|
||||
|
||||
export const serverMessageSchema = z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal(ServerMessageType.Hello),
|
||||
data: z.object({
|
||||
clientId: z.string(),
|
||||
}),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal(ServerMessageType.Pong),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal(ServerMessageType.Message),
|
||||
data: z.object({
|
||||
message: z.string(),
|
||||
}),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal(ServerMessageType.Data),
|
||||
data: z.unknown(),
|
||||
}),
|
||||
])
|
||||
|
||||
export type ServerMessage = z.infer<typeof serverMessageSchema>
|
||||
330
package-lock.json
generated
330
package-lock.json
generated
|
|
@ -41,6 +41,7 @@
|
|||
"js-tiktoken": "^1.0.19",
|
||||
"mammoth": "^1.8.0",
|
||||
"monaco-vscode-textmate-theme-converter": "^0.1.7",
|
||||
"node-ipc": "^12.0.0",
|
||||
"openai": "^4.78.1",
|
||||
"os-name": "^6.0.0",
|
||||
"p-wait-for": "^5.0.2",
|
||||
|
|
@ -74,6 +75,7 @@
|
|||
"@types/glob": "^8.1.0",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "20.x",
|
||||
"@types/node-ipc": "^9.2.3",
|
||||
"@types/string-similarity": "^4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
||||
"@typescript-eslint/parser": "^7.11.0",
|
||||
|
|
@ -6113,6 +6115,16 @@
|
|||
"form-data": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node-ipc": {
|
||||
"version": "9.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node-ipc/-/node-ipc-9.2.3.tgz",
|
||||
"integrity": "sha512-/MvSiF71fYf3+zwqkh/zkVkZj1hl1Uobre9EMFy08mqfJNAmpR0vmPgOUdEIDVgifxHj6G1vYMPLSBLLxoDACQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/pdf-parse": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/pdf-parse/-/pdf-parse-1.1.4.tgz",
|
||||
|
|
@ -6846,8 +6858,7 @@
|
|||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/bare-events": {
|
||||
"version": "2.5.0",
|
||||
|
|
@ -7521,8 +7532,7 @@
|
|||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
|
|
@ -7574,6 +7584,176 @@
|
|||
"node": ">=6.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz",
|
||||
"integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"glob": "^7.0.5",
|
||||
"minimatch": "^3.0.3",
|
||||
"mkdirp": "^1.0.4",
|
||||
"noms": "0.0.0",
|
||||
"through2": "^2.0.1",
|
||||
"untildify": "^4.0.0",
|
||||
"yargs": "^16.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"copyfiles": "copyfiles",
|
||||
"copyup": "copyfiles"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/cliui": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/copyfiles/node_modules/yargs-parser": {
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
|
|
@ -8041,6 +8221,15 @@
|
|||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/easy-stack": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz",
|
||||
"integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/easy-table": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz",
|
||||
|
|
@ -8668,6 +8857,28 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/event-pubsub": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-5.0.3.tgz",
|
||||
"integrity": "sha512-2QiHxshejKgJrYMzSI9MEHrvhmzxBL+eLyiM5IiyjDBySkgwS2+tdtnO3gbx8pEisu/yOFCIhfCb63gCEu0yBQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"copyfiles": "^2.4.0",
|
||||
"strong-type": "^0.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=13.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/event-pubsub/node_modules/strong-type": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/strong-type/-/strong-type-0.1.6.tgz",
|
||||
"integrity": "sha512-eJe5caH6Pi5oMMeQtIoBPpvNu/s4jiyb63u5tkHNnQXomK+puyQ5i+Z5iTLBr/xUz/pIcps0NSfzzFI34+gAXg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/event-target-shim": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||
|
|
@ -9299,8 +9510,7 @@
|
|||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
|
|
@ -10045,7 +10255,6 @@
|
|||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
|
|
@ -11395,6 +11604,27 @@
|
|||
"jiti": "lib/jiti-cli.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/js-message": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
|
||||
"integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/js-queue": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.2.tgz",
|
||||
"integrity": "sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"easy-stack": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tiktoken": {
|
||||
"version": "1.0.19",
|
||||
"resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.19.tgz",
|
||||
|
|
@ -12567,12 +12797,61 @@
|
|||
"integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-ipc": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-12.0.0.tgz",
|
||||
"integrity": "sha512-QHJ2gAJiqA3cM7cQiRjLsfCOBRB0TwQ6axYD4FSllQWipEbP6i7Se1dP8EzPKk5J1nCe27W69eqPmCoKyQ61Vg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"event-pubsub": "5.0.3",
|
||||
"js-message": "1.0.7",
|
||||
"js-queue": "2.0.2",
|
||||
"strong-type": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.18",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
|
||||
"integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/noms": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz",
|
||||
"integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "~1.0.31"
|
||||
}
|
||||
},
|
||||
"node_modules/noms/node_modules/isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/noms/node_modules/readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"node_modules/noms/node_modules/string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/normalize-package-data": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
||||
|
|
@ -14951,6 +15230,15 @@
|
|||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
||||
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
|
||||
},
|
||||
"node_modules/strong-type": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strong-type/-/strong-type-1.1.0.tgz",
|
||||
"integrity": "sha512-X5Z6riticuH5GnhUyzijfDi1SoXas8ODDyN7K8lJeQK+Jfi4dKdoJGL4CXTskY/ATBcN+rz5lROGn1tAUkOX7g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/summary": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/summary/-/summary-2.1.0.tgz",
|
||||
|
|
@ -15089,6 +15377,16 @@
|
|||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
|
||||
},
|
||||
"node_modules/through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readable-stream": "~2.3.6",
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/tmp": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
|
||||
|
|
@ -15463,6 +15761,15 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/untildify": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
|
||||
"integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
|
||||
|
|
@ -16062,6 +16369,15 @@
|
|||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@
|
|||
"js-tiktoken": "^1.0.19",
|
||||
"mammoth": "^1.8.0",
|
||||
"monaco-vscode-textmate-theme-converter": "^0.1.7",
|
||||
"node-ipc": "^12.0.0",
|
||||
"openai": "^4.78.1",
|
||||
"os-name": "^6.0.0",
|
||||
"p-wait-for": "^5.0.2",
|
||||
|
|
@ -403,6 +404,7 @@
|
|||
"@types/glob": "^8.1.0",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "20.x",
|
||||
"@types/node-ipc": "^9.2.3",
|
||||
"@types/string-similarity": "^4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
||||
"@typescript-eslint/parser": "^7.11.0",
|
||||
|
|
|
|||
|
|
@ -91,9 +91,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|||
private contextProxy: ContextProxy
|
||||
configManager: ConfigManager
|
||||
customModesManager: CustomModesManager
|
||||
get cwd() {
|
||||
return getWorkspacePath()
|
||||
}
|
||||
|
||||
constructor(
|
||||
readonly context: vscode.ExtensionContext,
|
||||
private readonly outputChannel: vscode.OutputChannel,
|
||||
|
|
@ -2745,6 +2743,12 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|||
await this.contextProxy.setValues(values)
|
||||
}
|
||||
|
||||
// cwd
|
||||
|
||||
get cwd() {
|
||||
return getWorkspacePath()
|
||||
}
|
||||
|
||||
// dev
|
||||
|
||||
async resetState() {
|
||||
|
|
|
|||
|
|
@ -5,14 +5,16 @@ import { ClineProvider } from "../core/webview/ClineProvider"
|
|||
|
||||
import { RooCodeAPI, RooCodeEvents, ConfigurationValues, TokenUsage } from "./roo-code"
|
||||
import { MessageHistory } from "./message-history"
|
||||
import { IpcClientMessageType, IpcServerMessageType, IpcServer } from "./ipc"
|
||||
|
||||
export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
|
||||
private readonly outputChannel: vscode.OutputChannel
|
||||
private readonly provider: ClineProvider
|
||||
private readonly history: MessageHistory
|
||||
private readonly tokenUsage: Record<string, TokenUsage>
|
||||
private readonly ipc?: IpcServer
|
||||
|
||||
constructor(outputChannel: vscode.OutputChannel, provider: ClineProvider) {
|
||||
constructor(outputChannel: vscode.OutputChannel, provider: ClineProvider, socketPath?: string) {
|
||||
super()
|
||||
|
||||
this.outputChannel = outputChannel
|
||||
|
|
@ -41,6 +43,30 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
|
|||
})
|
||||
|
||||
this.on("taskTokenUsageUpdated", (taskId, usage) => (this.tokenUsage[taskId] = usage))
|
||||
|
||||
if (socketPath) {
|
||||
this.ipc = new IpcServer(socketPath)
|
||||
this.ipc.listen()
|
||||
|
||||
this.ipc.on("message", (message) => {
|
||||
switch (message.type) {
|
||||
case IpcClientMessageType.StartNewTask:
|
||||
this.startNewTask(message.data.text, message.data.images)
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public override emit<K extends keyof RooCodeEvents>(
|
||||
eventName: K,
|
||||
...args: K extends keyof RooCodeEvents ? RooCodeEvents[K] : never
|
||||
) {
|
||||
if (this.ipc) {
|
||||
this.ipc.broadcast({ type: IpcServerMessageType.TaskEvent, data: { eventName, data: { ...args } } })
|
||||
}
|
||||
|
||||
return super.emit(eventName, ...args)
|
||||
}
|
||||
|
||||
public async startNewTask(text?: string, images?: string[]) {
|
||||
|
|
|
|||
262
src/exports/ipc.ts
Normal file
262
src/exports/ipc.ts
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
import EventEmitter from "node:events"
|
||||
import { Socket } from "node:net"
|
||||
import * as crypto from "node:crypto"
|
||||
|
||||
import ipc from "node-ipc"
|
||||
import { z } from "zod"
|
||||
|
||||
/**
|
||||
* IpcClient
|
||||
*/
|
||||
|
||||
export type IpcClientId = string
|
||||
|
||||
export enum IpcClientMessageType {
|
||||
Message = "Message",
|
||||
StartNewTask = "StartNewTask",
|
||||
}
|
||||
|
||||
export const ipcClientMessageSchema = z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal(IpcClientMessageType.StartNewTask),
|
||||
data: z.object({
|
||||
text: z.string(),
|
||||
images: z.array(z.string()).optional(),
|
||||
}),
|
||||
}),
|
||||
])
|
||||
|
||||
export type IpcClientMessage = z.infer<typeof ipcClientMessageSchema>
|
||||
|
||||
export interface IpcClientEvents {
|
||||
connect: []
|
||||
disconnect: []
|
||||
message: [data: IpcServerMessage]
|
||||
}
|
||||
|
||||
export class IpcClient extends EventEmitter<IpcClientEvents> {
|
||||
private readonly _socketPath: string
|
||||
private readonly _log: (...args: unknown[]) => void
|
||||
|
||||
private _isConnected = false
|
||||
private _clientId?: IpcClientId
|
||||
|
||||
constructor(socketPath: string, log = console.log) {
|
||||
super()
|
||||
|
||||
this._socketPath = socketPath
|
||||
this._log = log
|
||||
|
||||
ipc.config.silent = true
|
||||
|
||||
ipc.connectTo("benchmarkServer", this.socketPath, () => {
|
||||
ipc.of.benchmarkServer?.on("connect", (args) => this.onConnect(args))
|
||||
ipc.of.benchmarkServer?.on("disconnect", (args) => this.onDisconnect(args))
|
||||
ipc.of.benchmarkServer?.on("message", (data) => this.onMessage(data))
|
||||
})
|
||||
}
|
||||
|
||||
private onConnect(args: unknown) {
|
||||
if (this._isConnected) {
|
||||
return
|
||||
}
|
||||
|
||||
this.log("[client#onConnect]", args)
|
||||
this._isConnected = true
|
||||
this.emit("connect")
|
||||
}
|
||||
|
||||
private onDisconnect(args: unknown) {
|
||||
if (!this._isConnected) {
|
||||
return
|
||||
}
|
||||
|
||||
this.log("[client#onDisconnect]", args)
|
||||
this._isConnected = false
|
||||
this.emit("disconnect")
|
||||
}
|
||||
|
||||
private onMessage(data: unknown) {
|
||||
if (typeof data !== "object") {
|
||||
this._log("[client#onMessage] invalid data", data)
|
||||
return
|
||||
}
|
||||
|
||||
const result = ipcServerMessageSchema.safeParse(data)
|
||||
|
||||
if (!result.success) {
|
||||
this.log("[client#onMessage] invalid payload", result.error)
|
||||
return
|
||||
}
|
||||
|
||||
this.emit("message", result.data)
|
||||
}
|
||||
|
||||
private log(...args: unknown[]) {
|
||||
this._log(...args)
|
||||
}
|
||||
|
||||
public sendMessage(message: IpcClientMessage) {
|
||||
ipc.of.benchmarkServer?.emit("message", message)
|
||||
}
|
||||
|
||||
public disconnect() {
|
||||
try {
|
||||
ipc.disconnect("benchmarkServer")
|
||||
// @TODO: Should we set _disconnect here?
|
||||
} catch (error) {
|
||||
this.log("[client#disconnect] error disconnecting", error)
|
||||
}
|
||||
}
|
||||
|
||||
public get socketPath() {
|
||||
return this._socketPath
|
||||
}
|
||||
|
||||
public get clientId() {
|
||||
return this._clientId
|
||||
}
|
||||
|
||||
public get isConnected() {
|
||||
return this._isConnected
|
||||
}
|
||||
|
||||
public get isReady() {
|
||||
return this._isConnected && this._clientId !== undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* IpcServer
|
||||
*/
|
||||
|
||||
export enum IpcServerMessageType {
|
||||
Ack = "Ack",
|
||||
TaskEvent = "TaskEvent",
|
||||
}
|
||||
|
||||
export const ipcServerMessageSchema = z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal(IpcServerMessageType.Ack),
|
||||
data: z.object({ clientId: z.string() }),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal(IpcServerMessageType.TaskEvent),
|
||||
data: z.object({
|
||||
eventName: z.string(),
|
||||
data: z.unknown(),
|
||||
}),
|
||||
}),
|
||||
])
|
||||
|
||||
export type IpcServerMessage = z.infer<typeof ipcServerMessageSchema>
|
||||
|
||||
type IpcServerEvents = {
|
||||
connect: [id: IpcClientId]
|
||||
disconnect: [id: IpcClientId]
|
||||
message: [data: IpcClientMessage]
|
||||
}
|
||||
|
||||
export class IpcServer extends EventEmitter<IpcServerEvents> {
|
||||
private readonly _socketPath: string
|
||||
private readonly _log: (...args: unknown[]) => void
|
||||
private readonly _clients: Map<string, Socket>
|
||||
|
||||
private _isListening = false
|
||||
|
||||
constructor(socketPath: string, log = console.log) {
|
||||
super()
|
||||
|
||||
this._socketPath = socketPath
|
||||
this._log = log
|
||||
this._clients = new Map()
|
||||
}
|
||||
|
||||
public listen() {
|
||||
this._isListening = true
|
||||
|
||||
ipc.config.silent = true
|
||||
|
||||
ipc.serve(this.socketPath, () => {
|
||||
ipc.server.on("connect", (socket) => this.onConnect(socket))
|
||||
ipc.server.on("socket.disconnected", (socket) => this.onDisconnect(socket))
|
||||
ipc.server.on("message", (data) => this.onMessage(data))
|
||||
})
|
||||
|
||||
ipc.server.start()
|
||||
}
|
||||
|
||||
private onConnect(socket: Socket) {
|
||||
const clientId = crypto.randomBytes(6).toString("hex")
|
||||
this._clients.set(clientId, socket)
|
||||
this.log(`[server#onConnect] clientId = ${clientId}, # clients = ${this._clients.size}`)
|
||||
this.send(socket, { type: IpcServerMessageType.Ack, data: { clientId } })
|
||||
this.emit("connect", clientId)
|
||||
}
|
||||
|
||||
private onDisconnect(destroyedSocket: Socket) {
|
||||
let disconnectedClientId: IpcClientId | undefined
|
||||
|
||||
for (const [clientId, socket] of this._clients.entries()) {
|
||||
if (socket === destroyedSocket) {
|
||||
disconnectedClientId = clientId
|
||||
this._clients.delete(clientId)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
this.log(`[server#socket.disconnected] clientId = ${disconnectedClientId}, # clients = ${this._clients.size}`)
|
||||
|
||||
if (disconnectedClientId) {
|
||||
this.emit("disconnect", disconnectedClientId)
|
||||
}
|
||||
}
|
||||
|
||||
private onMessage(data: unknown) {
|
||||
if (typeof data !== "object") {
|
||||
this.log("[server#onMessage] invalid data", data)
|
||||
return
|
||||
}
|
||||
|
||||
const result = ipcClientMessageSchema.safeParse(data)
|
||||
|
||||
if (!result.success) {
|
||||
this.log("[server#onMessage] invalid payload", result.error)
|
||||
return
|
||||
}
|
||||
|
||||
const payload = result.data
|
||||
this.emit("message", payload)
|
||||
}
|
||||
|
||||
private log(...args: unknown[]) {
|
||||
this._log(...args)
|
||||
}
|
||||
|
||||
public broadcast(message: IpcServerMessage) {
|
||||
this.log("[server#broadcast] message =", message)
|
||||
ipc.server.broadcast("message", message)
|
||||
}
|
||||
|
||||
public send(client: IpcClientId | Socket, message: IpcServerMessage) {
|
||||
this.log("[server#send] message =", message)
|
||||
|
||||
if (typeof client === "string") {
|
||||
const socket = this._clients.get(client)
|
||||
|
||||
if (socket) {
|
||||
ipc.server.emit(socket, "message", message)
|
||||
}
|
||||
} else {
|
||||
ipc.server.emit(client, "message", message)
|
||||
}
|
||||
}
|
||||
|
||||
public get socketPath() {
|
||||
return this._socketPath
|
||||
}
|
||||
|
||||
public get isListening() {
|
||||
return this._isListening
|
||||
}
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
registerTerminalActions(context)
|
||||
|
||||
// Implements the `RooCodeAPI` interface.
|
||||
return new API(outputChannel, provider)
|
||||
return new API(outputChannel, provider, "/tmp/roo-code-ipc.sock")
|
||||
}
|
||||
|
||||
// This method is called when your extension is deactivated
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue