diff --git a/README.md b/README.md index a57e569..70df065 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,21 @@ cd ~/.config/opencode npm install @dataforxyz/agent-intercom-opencode ``` +For OpenCode v2, add the native v2 entrypoint to `opencode.json`: + +```json +{ + "plugins": ["@dataforxyz/agent-intercom-opencode/v2"] +} +``` + +The v2 entrypoint uses the v2 tool, session, permission, and event APIs directly. +It filters the public event stream by the plugin location before updating the +active session, preventing one directory's messages from being routed into a +different OpenCode pane. + +For OpenCode v1, continue with the server and TUI configuration below. + The packaged `dist` files are prebuilt. Add the server plugin to your normal OpenCode config (usually `~/.config/opencode/opencode.json`), replacing `/home/you` with your absolute home path: ```json diff --git a/dist/plugin-v2.mjs b/dist/plugin-v2.mjs new file mode 100644 index 0000000..0d4a728 --- /dev/null +++ b/dist/plugin-v2.mjs @@ -0,0 +1,3172 @@ +// opencode/plugin-v2.ts +import { resolve as resolve3 } from "node:path"; + +// opencode/plugin.ts +import { appendFileSync } from "fs"; +import { tool } from "@opencode-ai/plugin"; + +// opencode/runtime.ts +import { randomUUID as randomUUID4, createHash as createHash2 } from "crypto"; +import { spawnSync } from "child_process"; +import { basename as basename2 } from "path"; +import { cwd as processCwd } from "process"; + +// broker/client.ts +import { EventEmitter } from "events"; +import net from "net"; +import { randomUUID as randomUUID2 } from "crypto"; +import { types as nodeUtilTypes } from "node:util"; +import { + POLICY_SEMANTICS_HASH, + POLICY_SEMANTICS_VERSION +} from "@dataforxyz/agent-intercom-core"; +import { + parseBossControlEnvelope as parseBossControlEnvelope2 +} from "@dataforxyz/agent-intercom-core/boss"; +import { assertExactKeys as assertExactKeys2 } from "@dataforxyz/agent-intercom-core/canonical"; + +// broker/boss.ts +import { + BOSS_CONTROL_TYPES, + parseBossControlEnvelope, + parseBossParticipantBinding, + parseBossPolicyPrincipal, + parseFeatureRegistration +} from "@dataforxyz/agent-intercom-core/boss"; +import { + ContractValidationError, + assertExactKeys, + assertRecord +} from "@dataforxyz/agent-intercom-core/canonical"; +var CONTROL_KIND_BY_TYPE = { + "boss.assignment.created": "assignment_request", + "boss.assignment.accepted": "assignment_response", + "boss.assignment.checkpoint": "assignment_response", + "boss.assignment.submitted": "assignment_response", + "boss.assignment.rejected": "assignment_response", + "boss.assignment.cancelled": "lifecycle", + "boss.staffing.requested": "staffing", + "boss.staffing.resolved": "staffing", + "boss.review.requested": "review_request", + "boss.review.submitted": "review_result", + "boss.council.requested": "review_request", + "boss.council.submitted": "review_result", + "boss.proof.submitted": "proof", + "boss.worker.health": "health", + "boss.worker.blocked": "health", + "boss.worker.failed": "health", + "boss.worker.notice": "lifecycle", + "boss.worker.notice_delivery_failed": "lifecycle", + "boss.decision.required": "decision" +}; +if (Object.keys(CONTROL_KIND_BY_TYPE).length !== BOSS_CONTROL_TYPES.length) { + throw new Error("Boss control type mapping is incomplete"); +} +function parseBossSessionMetadata(value, sessionId) { + assertRecord(value, "$.boss"); + assertExactKeys(value, ["registration", "principal"], ["binding"], "$.boss"); + const metadata = value; + const registration = parseFeatureRegistration(metadata.registration); + const principal = parseBossPolicyPrincipal(metadata.principal); + if (registration.principalClass !== "boss-bound" || principal.principalClass !== "boss-private") { + throw new ContractValidationError("$.boss", "must contain Boss-bound registration and private principal metadata"); + } + if (registration.principalId !== sessionId || principal.principalId !== sessionId || registration.bossRunId !== principal.bossRunId || registration.participantId !== principal.participantId || registration.bindingEpoch !== principal.bindingEpoch) { + throw new ContractValidationError("$.boss", "registration and principal identity bindings must exactly match the session"); + } + const binding = metadata.binding === void 0 ? void 0 : parseBossParticipantBinding(metadata.binding); + if (principal.role === "controller") { + if (binding !== void 0) throw new ContractValidationError("$.boss.binding", "is forbidden for Controller principals"); + } else { + if (binding === void 0) throw new ContractValidationError("$.boss.binding", "is required for Boss participants"); + if (binding.sessionId !== sessionId || binding.bossRunId !== principal.bossRunId || binding.participantId !== principal.participantId || binding.role !== principal.role || binding.bindingEpoch !== principal.bindingEpoch || binding.state !== principal.state || binding.assignedManagerParticipantId !== principal.assignedManagerParticipantId) { + throw new ContractValidationError("$.boss.binding", "must exactly match the authenticated session principal"); + } + } + return { registration, principal, ...binding === void 0 ? {} : { binding } }; +} +function validatedBossMetadata(session) { + if (session.boss === void 0) return void 0; + return parseBossSessionMetadata(session.boss, session.id); +} +function parseBoundBossControl(value, sender) { + const envelope = parseBossControlEnvelope(value); + const boss = validatedBossMetadata(sender); + if (!boss) throw new ContractValidationError("$.envelope", "sender is not an authenticated Boss participant"); + if (envelope.bossRunId !== boss.principal.bossRunId || envelope.participantId !== boss.principal.participantId || envelope.bindingEpoch !== boss.principal.bindingEpoch) { + throw new ContractValidationError("$.envelope", "run, participant, and binding epoch must match the sender"); + } + return envelope; +} + +// broker/framing.ts +var MAX_FRAME_BYTES = 1024 * 1024; +function writeMessage(socket, msg) { + const json = JSON.stringify(msg); + const payload = Buffer.from(json, "utf-8"); + const header = Buffer.alloc(4); + header.writeUInt32BE(payload.length, 0); + socket.write(Buffer.concat([header, payload])); +} +function createMessageReader(onMessage, onError, maxFrameBytes = MAX_FRAME_BYTES) { + let buffer = Buffer.alloc(0); + function reportMessage(payload) { + let msg; + try { + msg = JSON.parse(payload.toString("utf-8")); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + onError(new Error(`Failed to parse intercom message: ${message}`, { cause: error })); + return false; + } + try { + onMessage(msg); + return true; + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + onError(new Error(`Failed to handle intercom message: ${message}`, { cause: error })); + return false; + } + } + return (data) => { + let remaining = data; + while (remaining.length > 0) { + if (buffer.length < 4) { + const headerBytes = Math.min(4 - buffer.length, remaining.length); + buffer = Buffer.concat([buffer, remaining.subarray(0, headerBytes)]); + remaining = remaining.subarray(headerBytes); + if (buffer.length < 4) { + return; + } + } + const length = buffer.readUInt32BE(0); + if (length > maxFrameBytes) { + buffer = Buffer.alloc(0); + onError(new Error(`Intercom frame length ${length} exceeds maximum ${maxFrameBytes} bytes`)); + return; + } + const missingPayloadBytes = length - Math.max(0, buffer.length - 4); + const payloadBytes = Math.min(missingPayloadBytes, remaining.length); + if (payloadBytes > 0) { + buffer = Buffer.concat([buffer, remaining.subarray(0, payloadBytes)]); + remaining = remaining.subarray(payloadBytes); + } + if (buffer.length < 4 + length) { + return; + } + const payload = buffer.subarray(4, 4 + length); + buffer = Buffer.alloc(0); + if (!reportMessage(payload)) { + return; + } + } + }; +} + +// outbound-outbox.ts +import { createHash } from "crypto"; +import { chmodSync as chmodSync2, existsSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2 } from "fs"; +import { join as join2 } from "path"; + +// broker/paths.ts +import { chmodSync, mkdirSync, readFileSync } from "fs"; +import { isAbsolute, join, resolve } from "path"; +import { homedir } from "os"; +var INTERCOM_DIR_MODE = 448; +var INTERCOM_RUNTIME_FILE_MODE = 384; +var INTERCOM_TCP_HOST = "127.0.0.1"; +var INTERCOM_PROTOCOL_NAME = "pi-intercom"; +var INTERCOM_PROTOCOL_VERSION = 3; +function sanitizePipeSegment(value) { + return value.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase() || "default"; +} +function getAgentDirPath(env = process.env, homeDir = homedir(), cwd = process.cwd()) { + const configured = env.PI_CODING_AGENT_DIR?.trim(); + if (!configured) { + return join(homeDir, ".pi/agent"); + } + return isAbsolute(configured) ? configured : resolve(cwd, configured); +} +function getIntercomDirPath(agentDir = getAgentDirPath()) { + return join(agentDir, "intercom"); +} +function shouldUseWindowsTcpTransport(platform = process.platform, env = process.env) { + if (platform !== "win32") { + return false; + } + const transport = env.PI_INTERCOM_TRANSPORT?.trim().toLowerCase(); + if (transport === "tcp") { + return true; + } + const legacyOptIn = env.PI_INTERCOM_TCP?.trim().toLowerCase(); + return legacyOptIn === "1" || legacyOptIn === "true"; +} +function getBrokerPortFilePath(intercomDir = getIntercomDirPath()) { + return join(intercomDir, "broker.port.json"); +} +function getBrokerSocketPath(platform = process.platform, agentDir = getAgentDirPath()) { + if (platform === "win32") { + return `\\\\.\\pipe\\pi-intercom-${sanitizePipeSegment(agentDir)}`; + } + return join(getIntercomDirPath(agentDir), "broker.sock"); +} +function getBrokerConnectTarget(platform = process.platform, env = process.env, intercomDir = getIntercomDirPath(getAgentDirPath(env))) { + if (shouldUseWindowsTcpTransport(platform, env)) { + const endpointFile = getBrokerPortFilePath(intercomDir); + const raw = readFileSync(endpointFile, "utf-8"); + const parsed = JSON.parse(raw); + if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) { + throw new Error(`Invalid intercom TCP endpoint at ${endpointFile}: expected a JSON object`); + } + const endpoint = parsed; + if (endpoint.transport !== "tcp" || endpoint.host !== INTERCOM_TCP_HOST || typeof endpoint.port !== "number" || !Number.isSafeInteger(endpoint.port) || endpoint.port <= 0 || endpoint.port > 65535 || typeof endpoint.stateId !== "string" || endpoint.stateId.length === 0) { + throw new Error(`Invalid intercom TCP endpoint at ${endpointFile}`); + } + return { transport: "tcp", host: endpoint.host, port: endpoint.port, stateId: endpoint.stateId }; + } + return getBrokerSocketPath(platform, getAgentDirPath(env)); +} +function ensureIntercomRuntimeDir(intercomDir = getIntercomDirPath(), platform = process.platform) { + mkdirSync(intercomDir, { recursive: true, mode: INTERCOM_DIR_MODE }); + if (platform !== "win32") { + chmodSync(intercomDir, INTERCOM_DIR_MODE); + } +} +function restrictIntercomRuntimeFile(filePath, platform = process.platform) { + if (platform !== "win32") { + chmodSync(filePath, INTERCOM_RUNTIME_FILE_MODE); + } +} + +// durable-json.ts +import { randomUUID } from "crypto"; +import { closeSync, fsyncSync, openSync, renameSync, writeFileSync } from "fs"; +import { dirname } from "path"; +var DURABLE_JSON_FILE_OPERATIONS = Object.freeze({ + writeFile(filePath, contents, options) { + writeFileSync(filePath, contents, options); + }, + open(filePath, flags) { + return openSync(filePath, flags); + }, + fsync(fileDescriptor) { + fsyncSync(fileDescriptor); + }, + close(fileDescriptor) { + closeSync(fileDescriptor); + }, + rename(from, to) { + renameSync(from, to); + }, + restrict(filePath) { + restrictIntercomRuntimeFile(filePath); + }, + platform: process.platform +}); +function writeDurableJson(filePath, value, operations = DURABLE_JSON_FILE_OPERATIONS) { + const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`; + operations.writeFile(temporaryPath, JSON.stringify(value), { encoding: "utf-8", mode: INTERCOM_RUNTIME_FILE_MODE }); + const fileDescriptor = operations.open(temporaryPath, "r"); + try { + operations.fsync(fileDescriptor); + } finally { + operations.close(fileDescriptor); + } + operations.rename(temporaryPath, filePath); + operations.restrict(filePath); + if (operations.platform !== "win32") { + const directoryDescriptor = operations.open(dirname(filePath), "r"); + try { + operations.fsync(directoryDescriptor); + } finally { + operations.close(directoryDescriptor); + } + } +} + +// outbound-outbox.ts +var OUTBOX_STATE_VERSION = 1; +var MAX_OUTBOX_MESSAGES = 256; +function fingerprint(entry) { + return JSON.stringify({ + to: entry.to, + replyTo: entry.message.replyTo, + expectsReply: entry.message.expectsReply, + content: entry.message.content + }); +} +function isStoredOutboundMessage(value) { + if (typeof value !== "object" || value === null || Array.isArray(value)) return false; + const entry = value; + if (typeof entry.to !== "string" || typeof entry.queuedAt !== "number") return false; + if (typeof entry.message !== "object" || entry.message === null || Array.isArray(entry.message)) return false; + const message = entry.message; + return typeof message.id === "string" && typeof message.timestamp === "number" && typeof message.content === "object" && message.content !== null && typeof message.content.text === "string"; +} +function fileName(sessionId) { + return `${createHash("sha256").update(sessionId).digest("hex")}.json`; +} +var PersistentOutboundOutbox = class { + directory; + filePath; + state; + constructor(sessionId, intercomDir = getIntercomDirPath()) { + ensureIntercomRuntimeDir(intercomDir); + this.directory = join2(intercomDir, "outbox"); + mkdirSync2(this.directory, { recursive: true, mode: INTERCOM_DIR_MODE }); + if (process.platform !== "win32") chmodSync2(this.directory, INTERCOM_DIR_MODE); + this.filePath = join2(this.directory, fileName(sessionId)); + this.state = this.load(); + } + list() { + return this.state.entries.map((entry) => ({ ...entry, message: { ...entry.message, content: { ...entry.message.content } } })); + } + enqueue(to, message) { + const existing = this.state.entries.find((entry) => entry.message.id === message.id); + if (existing) { + if (fingerprint(existing) !== fingerprint({ to, message })) { + throw new Error(`Message ID ${message.id} is already queued with a different payload`); + } + return "existing"; + } + if (this.state.entries.length >= MAX_OUTBOX_MESSAGES) { + throw new Error(`Durable outbox is full (${MAX_OUTBOX_MESSAGES} messages)`); + } + this.state.entries.push({ to, message, queuedAt: Date.now() }); + this.persist(); + return "added"; + } + remove(messageId) { + const remaining = this.state.entries.filter((entry) => entry.message.id !== messageId); + if (remaining.length === this.state.entries.length) return; + this.state.entries = remaining; + this.persist(); + } + clear() { + if (this.state.entries.length === 0) return; + this.state.entries = []; + this.persist(); + } + load() { + if (!existsSync(this.filePath)) return { version: OUTBOX_STATE_VERSION, entries: [] }; + try { + const parsed = JSON.parse(readFileSync2(this.filePath, "utf-8")); + if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error("expected object"); + const state = parsed; + if (state.version !== OUTBOX_STATE_VERSION || !Array.isArray(state.entries) || !state.entries.every(isStoredOutboundMessage)) { + throw new Error("invalid outbox state"); + } + return { version: OUTBOX_STATE_VERSION, entries: state.entries }; + } catch { + const corruptPath = `${this.filePath}.corrupt-${Date.now()}`; + renameSync2(this.filePath, corruptPath); + restrictIntercomRuntimeFile(corruptPath); + return { version: OUTBOX_STATE_VERSION, entries: [] }; + } + } + persist() { + writeDurableJson(this.filePath, this.state); + } +}; + +// broker/access-credential.ts +import { readFileSync as readFileSync3 } from "fs"; +var ACCESS_CREDENTIAL_ENV = "AGENT_INTERCOM_ACCESS_CREDENTIAL_PATH"; +var ACCESS_CREDENTIAL_VERSION = 1; +function nonEmptyString(value) { + return typeof value === "string" && value.length > 0 && !value.includes("\0"); +} +function loadRemoteAccessCredential(env = process.env) { + const path = env[ACCESS_CREDENTIAL_ENV]?.trim(); + if (!path) return void 0; + const parsed = JSON.parse(readFileSync3(path, "utf8")); + if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) { + throw new Error(`Invalid Agent Intercom access credential at ${path}`); + } + const credential = parsed; + if (nonEmptyString(credential.enrollmentToken)) { + return { path, access: { enrollmentToken: credential.enrollmentToken }, enrollment: true }; + } + if (credential.version === ACCESS_CREDENTIAL_VERSION && nonEmptyString(credential.sessionCredential) && nonEmptyString(credential.sessionId) && typeof credential.generation === "number" && Number.isSafeInteger(credential.generation) && credential.generation > 0) { + return { + path, + access: { + sessionCredential: credential.sessionCredential, + sessionId: credential.sessionId, + generation: credential.generation + }, + enrollment: false + }; + } + throw new Error(`Invalid Agent Intercom access credential at ${path}`); +} +function writeRemoteSessionCredential(path, sessionId, metadata) { + if (!metadata.sessionCredential) { + throw new Error("Remote enrollment response omitted the session credential"); + } + writeDurableJson(path, { + version: ACCESS_CREDENTIAL_VERSION, + sessionCredential: metadata.sessionCredential, + sessionId, + generation: metadata.generation + }); +} + +// broker/client.ts +function toError(error) { + return error instanceof Error ? error : new Error(String(error)); +} +function connectToBrokerTarget(target) { + return typeof target === "string" ? net.connect(target) : net.connect({ host: target.host, port: target.port }); +} +function isAttachment(value) { + if (typeof value !== "object" || value === null) { + return false; + } + const attachment = value; + if (attachment.type !== "file" && attachment.type !== "snippet" && attachment.type !== "context") { + return false; + } + if (typeof attachment.name !== "string" || typeof attachment.content !== "string") { + return false; + } + return attachment.language === void 0 || typeof attachment.language === "string"; +} +function isMessage(value) { + if (typeof value !== "object" || value === null) { + return false; + } + const message = value; + if (typeof message.id !== "string" || typeof message.timestamp !== "number") { + return false; + } + if (message.replyTo !== void 0 && typeof message.replyTo !== "string") { + return false; + } + if (message.expectsReply !== void 0 && typeof message.expectsReply !== "boolean") { + return false; + } + if (typeof message.content !== "object" || message.content === null) { + return false; + } + const content = message.content; + if (typeof content.text !== "string") { + return false; + } + return content.attachments === void 0 || Array.isArray(content.attachments) && content.attachments.every(isAttachment); +} +var PRE_ACCEPT_BOSS_CONTROL_FAILURE_CODES = [ + "INVALID_BOSS_CONTROL", + "SESSION_NOT_FOUND", + "CONFLICTING_MESSAGE_ID", + "TOO_MANY_PENDING_DELIVERIES", + "BOSS_CONTROL_DENIED" +]; +var POST_ACCEPT_BOSS_CONTROL_FAILURE_CODES = [ + "BOSS_CONTROL_DENIED", + "RECIPIENT_DISCONNECTED", + "SENDER_DISCONNECTED", + "DELIVERY_TIMEOUT" +]; +function isBossControlFailureCode(value, accepted) { + return typeof value === "string" && (accepted ? POST_ACCEPT_BOSS_CONTROL_FAILURE_CODES : PRE_ACCEPT_BOSS_CONTROL_FAILURE_CODES).includes(value); +} +function exactBossControlFrame(frame, required, path) { + assertExactKeys2(frame, required, [], path); +} +function bossControlFrameString(value, path) { + if (typeof value !== "string" || value.length === 0) throw new Error(`${path} must be a non-empty string`); +} +function isSessionInfo(value) { + if (typeof value !== "object" || value === null) { + return false; + } + const session = value; + if (typeof session.id !== "string" || typeof session.cwd !== "string" || typeof session.model !== "string" || typeof session.pid !== "number" || typeof session.startedAt !== "number" || typeof session.lastActivity !== "number") { + return false; + } + if (session.name !== void 0 && typeof session.name !== "string") { + return false; + } + if (session.status !== void 0 && typeof session.status !== "string") { + return false; + } + if (session.peerUid !== void 0 && typeof session.peerUid !== "number") { + return false; + } + if (session.trustedLocal !== void 0 && typeof session.trustedLocal !== "boolean") return false; + if (session.origin !== void 0 && session.origin !== "local" && session.origin !== "remote") return false; + if (session.remoteHostId !== void 0 && typeof session.remoteHostId !== "string") return false; + if (session.parentSessionId !== void 0 && typeof session.parentSessionId !== "string") return false; + if (session.rootSessionId !== void 0 && typeof session.rootSessionId !== "string") return false; + if (session.generation !== void 0 && (typeof session.generation !== "number" || !Number.isSafeInteger(session.generation))) return false; + if (session.canDelegate !== void 0 && typeof session.canDelegate !== "boolean") return false; + for (const field of ["depth", "maxDepth", "maxChildren"]) { + if (session[field] !== void 0 && (typeof session[field] !== "number" || !Number.isSafeInteger(session[field]))) return false; + } + return session.boss === void 0; +} +var BOSS_SESSION_REQUIRED_FIELDS = [ + "id", + "cwd", + "model", + "pid", + "startedAt", + "lastActivity", + "boss" +]; +var BOSS_SESSION_OPTIONAL_FIELDS = [ + "name", + "status", + "peerUid", + "trustedLocal", + "origin", + "remoteHostId", + "parentSessionId", + "rootSessionId", + "generation", + "canDelegate", + "depth", + "maxDepth", + "maxChildren" +]; +function snapshotBossData(value, path, seen = /* @__PURE__ */ new WeakSet(), depth = 0) { + if (value === null || typeof value === "string" || typeof value === "boolean") return value; + if (typeof value === "number") { + if (!Number.isFinite(value) || Object.is(value, -0)) throw new Error(`${path} must be a JSON number`); + return value; + } + if (typeof value !== "object" || nodeUtilTypes.isProxy(value)) { + throw new Error(`${path} must be unproxied broker-owned data`); + } + if (depth >= 32 || seen.has(value)) throw new Error(`${path} must be an acyclic bounded data tree`); + seen.add(value); + if (Array.isArray(value)) { + if (Object.getPrototypeOf(value) !== Array.prototype) throw new Error(`${path} must be a plain array`); + const lengthDescriptor = Object.getOwnPropertyDescriptor(value, "length"); + if (lengthDescriptor === void 0 || !Object.hasOwn(lengthDescriptor, "value") || !Number.isSafeInteger(lengthDescriptor.value) || lengthDescriptor.value < 0) { + throw new Error(`${path} must be a dense array`); + } + const entries = /* @__PURE__ */ new Map(); + for (const key of Reflect.ownKeys(value)) { + if (key === "length") continue; + if (typeof key !== "string") throw new Error(`${path} must not contain symbol properties`); + const index = Number(key); + if (!Number.isInteger(index) || index < 0 || index >= lengthDescriptor.value || String(index) !== key) { + throw new Error(`${path}.${key} is not a supported array index`); + } + const descriptor = Object.getOwnPropertyDescriptor(value, key); + if (descriptor === void 0 || !descriptor.enumerable || !Object.hasOwn(descriptor, "value")) { + throw new Error(`${path}[${index}] must be an enumerable data property`); + } + entries.set(index, snapshotBossData(descriptor.value, `${path}[${index}]`, seen, depth + 1)); + } + if (entries.size !== lengthDescriptor.value) throw new Error(`${path} must not contain sparse array holes`); + return Array.from({ length: lengthDescriptor.value }, (_, index) => entries.get(index)); + } + if (Object.getPrototypeOf(value) !== Object.prototype) throw new Error(`${path} must be a plain object`); + const snapshot = {}; + for (const key of Reflect.ownKeys(value)) { + if (typeof key !== "string") throw new Error(`${path} must not contain symbol properties`); + const descriptor = Object.getOwnPropertyDescriptor(value, key); + if (descriptor === void 0 || !descriptor.enumerable || !Object.hasOwn(descriptor, "value")) { + throw new Error(`${path}.${key} must be an enumerable data property`); + } + Object.defineProperty(snapshot, key, { + configurable: true, + enumerable: true, + value: snapshotBossData(descriptor.value, `${path}.${key}`, seen, depth + 1), + writable: true + }); + } + return snapshot; +} +function authoritativeBossSessionInfo(value) { + try { + const snapshot = snapshotBossData(value, "$.boss_control.from"); + if (typeof snapshot !== "object" || snapshot === null || Array.isArray(snapshot)) return void 0; + const session = snapshot; + assertExactKeys2( + session, + [...BOSS_SESSION_REQUIRED_FIELDS], + [...BOSS_SESSION_OPTIONAL_FIELDS], + "$.boss_control.from" + ); + const { boss, ...ordinaryFields } = session; + if (!isSessionInfo(ordinaryFields)) return void 0; + const parsedBoss = parseBossSessionMetadata(boss, ordinaryFields.id); + if (parsedBoss.registration.state !== "active" || !parsedBoss.registration.brokerIdentityVerified || parsedBoss.principal.state !== "active" || parsedBoss.binding !== void 0 && parsedBoss.binding.state !== "active") { + return void 0; + } + return { ...ordinaryFields, boss: parsedBoss }; + } catch { + return void 0; + } +} +function isRemoteAccessMetadata(value) { + if (typeof value !== "object" || value === null || Array.isArray(value)) return false; + const access = value; + return access.origin === "remote" && typeof access.remoteHostId === "string" && typeof access.parentSessionId === "string" && typeof access.rootSessionId === "string" && typeof access.generation === "number" && Number.isSafeInteger(access.generation) && access.generation > 0 && typeof access.canDelegate === "boolean" && typeof access.depth === "number" && Number.isSafeInteger(access.depth) && typeof access.maxDepth === "number" && Number.isSafeInteger(access.maxDepth) && typeof access.maxChildren === "number" && Number.isSafeInteger(access.maxChildren) && (access.sessionCredential === void 0 || typeof access.sessionCredential === "string"); +} +var IntercomClient = class extends EventEmitter { + socket = null; + _sessionId = null; + pendingSends = /* @__PURE__ */ new Map(); + pendingLists = /* @__PURE__ */ new Map(); + pendingAskControls = /* @__PURE__ */ new Map(); + pendingBossControls = /* @__PURE__ */ new Map(); + outbox = null; + remoteAccessCredential; + disconnecting = false; + disconnectError = null; + failPending(error) { + for (const pending of this.pendingSends.values()) { + pending.reject(error); + } + this.pendingSends.clear(); + for (const pending of this.pendingLists.values()) { + pending.reject(error); + } + this.pendingLists.clear(); + for (const pending of this.pendingAskControls.values()) { + clearTimeout(pending.timeout); + pending.resolve(false); + } + this.pendingAskControls.clear(); + for (const pending of this.pendingBossControls.values()) pending.reject(error); + this.pendingBossControls.clear(); + } + get sessionId() { + return this._sessionId; + } + get outboxSize() { + return this.outbox?.list().length ?? 0; + } + isConnected() { + const socket = this.socket; + return Boolean(socket && this._sessionId && !this.disconnecting && !socket.destroyed && !socket.writableEnded && socket.writable); + } + requireActiveSocket() { + if (this.disconnecting) { + throw new Error("Client disconnecting"); + } + const socket = this.socket; + if (!socket || !this._sessionId) { + throw new Error("Not connected"); + } + if (socket.destroyed || socket.writableEnded || !socket.writable) { + throw new Error("Client disconnected"); + } + return socket; + } + connect(session, sessionId) { + if (this.socket) { + return Promise.reject(new Error("Already connected")); + } + return new Promise((resolve4, reject) => { + let socket; + let target; + try { + target = getBrokerConnectTarget(); + this.remoteAccessCredential = loadRemoteAccessCredential(); + socket = connectToBrokerTarget(target); + } catch (error) { + reject(toError(error)); + return; + } + this.socket = socket; + this.disconnectError = null; + let settled = false; + const timeout = setTimeout(() => { + if (!this._sessionId) { + cleanupConnectionAttempt(); + cleanupSocketListeners(); + if (this.socket === socket) { + this.socket = null; + } + socket.destroy(); + reject(new Error("Connection timeout")); + } + }, 1e4); + let connectionEstablished = false; + const onRegistered = () => { + settled = true; + connectionEstablished = true; + cleanupConnectionAttempt(); + resolve4(); + }; + const onError = (err) => { + settled = true; + cleanupConnectionAttempt(); + cleanupSocketListeners(); + if (this.socket === socket) { + this.socket = null; + } + socket.destroy(); + reject(err); + }; + const onClose = () => { + const wasConnecting = !settled && !this._sessionId; + const wasDisconnecting = this.disconnecting; + const disconnectError = this.disconnectError ?? new Error("Client disconnected"); + this.disconnecting = false; + cleanupConnectionAttempt(); + cleanupSocketListeners(); + this.failPending(disconnectError); + if (this.socket === socket) { + this.socket = null; + } + this._sessionId = null; + this.disconnectError = null; + if (connectionEstablished && !wasDisconnecting) { + this.emit("disconnected", disconnectError); + } + if (wasConnecting) { + reject(new Error("Connection closed before registration")); + } + }; + const onSocketError = (err) => { + if (connectionEstablished) { + this.disconnectError = err; + this.emit("error", err); + } + }; + const onReaderError = (error) => { + const protocolError = new Error(`Intercom protocol error: ${error.message}`, { cause: error }); + if (!connectionEstablished) { + onError(protocolError); + return; + } + this.disconnectError = protocolError; + this.emit("error", protocolError); + socket.destroy(); + }; + const reader = createMessageReader((msg) => { + this.handleBrokerMessage(msg); + }, onReaderError); + const cleanupConnectionAttempt = () => { + this.off("_registered", onRegistered); + socket.off("error", onError); + clearTimeout(timeout); + }; + const cleanupSocketListeners = () => { + socket.off("data", reader); + socket.off("error", onSocketError); + socket.off("close", onClose); + }; + socket.on("data", reader); + socket.on("error", onError); + socket.on("close", onClose); + socket.on("error", onSocketError); + this.once("_registered", onRegistered); + try { + writeMessage(socket, { + type: "register", + protocol: INTERCOM_PROTOCOL_NAME, + version: INTERCOM_PROTOCOL_VERSION, + session, + ...!this.remoteAccessCredential && sessionId ? { sessionId } : {}, + ...this.remoteAccessCredential ? { access: this.remoteAccessCredential.access } : {}, + ...typeof target === "string" ? {} : { stateId: target.stateId } + }); + } catch (error) { + cleanupConnectionAttempt(); + cleanupSocketListeners(); + if (this.socket === socket) { + this.socket = null; + } + socket.destroy(); + reject(toError(error)); + } + }); + } + handleBrokerMessage(msg) { + if (typeof msg !== "object" || msg === null || !("type" in msg) || typeof msg.type !== "string") { + throw new Error("Invalid broker message"); + } + const brokerMessage = msg; + if (this._sessionId === null && brokerMessage.type !== "registered" && brokerMessage.type !== "error") { + throw new Error(`Received ${brokerMessage.type} before registered`); + } + switch (brokerMessage.type) { + case "registered": { + if (typeof brokerMessage.sessionId !== "string" || brokerMessage.protocol !== INTERCOM_PROTOCOL_NAME || brokerMessage.version !== INTERCOM_PROTOCOL_VERSION) { + throw new Error("Invalid registered message"); + } + if (brokerMessage.boss !== void 0 || brokerMessage.capabilities !== void 0) { + throw new Error("Ordinary registration must not contain feature or Boss metadata"); + } + if (this._sessionId !== null) { + throw new Error("Received duplicate registered message"); + } + if (this.remoteAccessCredential) { + const contract = brokerMessage.remoteAccess; + const contractFields = typeof contract === "object" && contract !== null ? contract : void 0; + if (!contractFields || contractFields.feature !== "remote-access-v1" || contractFields.policySemanticsVersion !== POLICY_SEMANTICS_VERSION || contractFields.policySemanticsHash !== POLICY_SEMANTICS_HASH) { + throw new Error("Remote Intercom policy contract is absent or incompatible"); + } + if (!isRemoteAccessMetadata(brokerMessage.access)) { + throw new Error("Remote Intercom registration omitted broker-owned provenance"); + } + if (this.remoteAccessCredential.enrollment) { + writeRemoteSessionCredential(this.remoteAccessCredential.path, brokerMessage.sessionId, brokerMessage.access); + } else { + const reconnect = this.remoteAccessCredential.access; + if (!("sessionId" in reconnect) || reconnect.sessionId !== brokerMessage.sessionId || reconnect.generation !== brokerMessage.access.generation) { + throw new Error("Remote Intercom reconnect identity or generation changed unexpectedly"); + } + } + } + this._sessionId = brokerMessage.sessionId; + this.outbox = new PersistentOutboundOutbox(brokerMessage.sessionId); + this.replayOutbox(); + this.emit("_registered", { type: "registered", sessionId: brokerMessage.sessionId }); + break; + } + case "sessions": { + const { requestId, sessions } = brokerMessage; + if (typeof requestId !== "string" || !Array.isArray(sessions) || !sessions.every(isSessionInfo)) { + throw new Error("Invalid sessions message"); + } + const pending = this.pendingLists.get(requestId); + if (!pending) { + return; + } + this.pendingLists.delete(requestId); + pending.resolve(sessions); + break; + } + case "message": { + const { deliveryId, from, message } = brokerMessage; + if (typeof deliveryId !== "string" || !isSessionInfo(from) || !isMessage(message)) { + throw new Error("Invalid message event"); + } + this.emit("message", from, message, deliveryId); + break; + } + case "boss_control": { + const { deliveryId, envelope } = brokerMessage; + const from = authoritativeBossSessionInfo(brokerMessage.from); + if (typeof deliveryId !== "string" || from === void 0) throw new Error("Invalid boss_control event"); + const parsed = parseBoundBossControl( + snapshotBossData(envelope, "$.boss_control.envelope"), + from + ); + this.emit("boss_control", from, parsed, deliveryId); + break; + } + case "boss_control_accepted": { + exactBossControlFrame(brokerMessage, ["type", "messageId", "deliveryId"], "$.boss_control_accepted"); + const { deliveryId, messageId } = brokerMessage; + bossControlFrameString(deliveryId, "$.boss_control_accepted.deliveryId"); + bossControlFrameString(messageId, "$.boss_control_accepted.messageId"); + const pending = this.pendingBossControls.get(messageId); + if (!pending) break; + if (pending.accepted) throw new Error("Duplicate Boss control acceptance"); + if (pending.deliveryId !== void 0) throw new Error("Boss control acceptance state is contradictory"); + pending.accepted = true; + pending.deliveryId = deliveryId; + break; + } + case "boss_control_delivered": { + exactBossControlFrame(brokerMessage, ["type", "messageId", "deliveryId"], "$.boss_control_delivered"); + const { deliveryId, messageId } = brokerMessage; + bossControlFrameString(deliveryId, "$.boss_control_delivered.deliveryId"); + bossControlFrameString(messageId, "$.boss_control_delivered.messageId"); + const pending = this.pendingBossControls.get(messageId); + if (!pending) break; + if (!pending.accepted || pending.deliveryId !== deliveryId) { + throw new Error("Boss control delivery did not follow matching acceptance"); + } + this.pendingBossControls.delete(messageId); + pending.resolve({ id: messageId, accepted: true, delivered: true, deliveryId }); + break; + } + case "boss_control_failed": { + const { accepted } = brokerMessage; + if (typeof accepted !== "boolean") throw new Error("Invalid boss_control_failed message"); + exactBossControlFrame( + brokerMessage, + accepted ? ["type", "messageId", "deliveryId", "accepted", "code", "reason"] : ["type", "messageId", "accepted", "code", "reason"], + "$.boss_control_failed" + ); + const { code, deliveryId, messageId, reason } = brokerMessage; + if (!isBossControlFailureCode(code, accepted) || typeof reason !== "string" || reason.length === 0) { + throw new Error("Invalid boss_control_failed message"); + } + bossControlFrameString(messageId, "$.boss_control_failed.messageId"); + if (accepted) bossControlFrameString(deliveryId, "$.boss_control_failed.deliveryId"); + const pending = this.pendingBossControls.get(messageId); + if (!pending) break; + if (accepted !== pending.accepted) throw new Error("Boss control failure acceptance state is inconsistent"); + if (accepted && pending.deliveryId !== deliveryId) { + throw new Error("Boss control failure did not follow matching acceptance"); + } + this.pendingBossControls.delete(messageId); + pending.resolve({ + id: messageId, + accepted, + delivered: false, + code, + reason, + ...accepted ? { deliveryId } : {} + }); + break; + } + case "delivery_accepted": { + const { deliveryId, messageId } = brokerMessage; + if (typeof deliveryId !== "string" || typeof messageId !== "string") { + throw new Error("Invalid delivery_accepted message"); + } + const pending = this.pendingSends.get(messageId); + if (!pending) { + return; + } + pending.accepted = true; + pending.deliveryId = deliveryId; + this.emit("delivery_accepted", messageId, deliveryId); + break; + } + case "delivered": { + const { deliveryId, messageId } = brokerMessage; + if (typeof deliveryId !== "string" || typeof messageId !== "string") { + throw new Error("Invalid delivered message"); + } + this.outbox?.remove(messageId); + const pending = this.pendingSends.get(messageId); + if (!pending) { + this.emit("outbox_delivered", messageId, deliveryId); + return; + } + this.pendingSends.delete(messageId); + pending.resolve({ id: messageId, accepted: true, delivered: true, deliveryId }); + break; + } + case "delivery_failed": { + const { accepted, code, messageId, reason } = brokerMessage; + if (typeof accepted !== "boolean" || typeof code !== "string" || typeof messageId !== "string" || typeof reason !== "string") { + throw new Error("Invalid delivery_failed message"); + } + this.outbox?.remove(messageId); + const pending = this.pendingSends.get(messageId); + if (!pending) { + this.emit("outbox_failed", messageId, code, reason); + return; + } + this.pendingSends.delete(messageId); + pending.resolve({ + id: messageId, + accepted, + delivered: false, + code, + reason, + ...pending.deliveryId ? { deliveryId: pending.deliveryId } : {} + }); + break; + } + case "ask_deferred": { + const { fromSessionId, messageId } = brokerMessage; + if (typeof fromSessionId !== "string" || typeof messageId !== "string") { + throw new Error("Invalid ask_deferred message"); + } + this.emit("ask_deferred", messageId, fromSessionId); + break; + } + case "ask_cancelled": { + const { fromSessionId, messageId, reason } = brokerMessage; + if (typeof fromSessionId !== "string" || typeof messageId !== "string" || typeof reason !== "string") { + throw new Error("Invalid ask_cancelled message"); + } + this.emit("ask_cancelled", messageId, fromSessionId, reason); + break; + } + case "ask_control_result": { + const { action, applied, messageId, requestId } = brokerMessage; + if (action !== "defer" && action !== "cancel" || typeof applied !== "boolean" || typeof messageId !== "string" || typeof requestId !== "string") { + throw new Error("Invalid ask_control_result message"); + } + const pending = this.pendingAskControls.get(requestId); + if (!pending) return; + clearTimeout(pending.timeout); + this.pendingAskControls.delete(requestId); + pending.resolve(applied); + break; + } + case "session_joined": { + if (!isSessionInfo(brokerMessage.session)) { + throw new Error("Invalid session_joined message"); + } + this.emit("session_joined", brokerMessage.session); + break; + } + case "session_left": { + if (typeof brokerMessage.sessionId !== "string") { + throw new Error("Invalid session_left message"); + } + this.emit("session_left", brokerMessage.sessionId); + break; + } + case "presence_update": { + if (!isSessionInfo(brokerMessage.session)) { + throw new Error("Invalid presence_update message"); + } + this.emit("presence_update", brokerMessage.session); + break; + } + case "error": { + if (typeof brokerMessage.code !== "string" || typeof brokerMessage.error !== "string") { + throw new Error("Invalid error message"); + } + if (this._sessionId === null) { + const error2 = new Error(brokerMessage.error); + error2.code = brokerMessage.code; + throw error2; + } + const error = new Error(brokerMessage.error); + error.code = brokerMessage.code; + this.emit("error", error); + break; + } + default: + throw new Error(`Unknown broker message type: ${brokerMessage.type}`); + } + } + async disconnect(preserveAsks = false) { + const socket = this.socket; + if (!socket) { + return; + } + this.disconnecting = true; + this.disconnectError = null; + this.failPending(new Error("Client disconnected")); + if (!preserveAsks) this.outbox?.clear(); + await new Promise((resolve4) => { + let settled = false; + const finish = () => { + if (settled) { + return; + } + settled = true; + clearTimeout(timeout); + socket.off("close", onClose); + socket.off("error", onError); + resolve4(); + }; + const onClose = () => finish(); + const onError = () => { + socket.destroy(); + }; + const timeout = setTimeout(() => { + socket.destroy(); + }, 2e3); + socket.once("close", onClose); + socket.once("error", onError); + try { + writeMessage(socket, { type: "unregister", ...preserveAsks ? { preserveAsks: true } : {} }); + socket.end(); + } catch { + socket.destroy(); + } + }); + } + listSessions() { + let socket; + try { + socket = this.requireActiveSocket(); + } catch (error) { + return Promise.reject(toError(error)); + } + return new Promise((resolve4, reject) => { + const requestId = randomUUID2(); + const wrappedResolve = (sessions) => { + clearTimeout(timeout); + resolve4(sessions); + }; + const wrappedReject = (error) => { + clearTimeout(timeout); + reject(error); + }; + const timeout = setTimeout(() => { + if (this.pendingLists.has(requestId)) { + this.pendingLists.delete(requestId); + wrappedReject(new Error("List sessions timeout")); + } + }, 5e3); + this.pendingLists.set(requestId, { resolve: wrappedResolve, reject: wrappedReject }); + try { + writeMessage(socket, { type: "list", requestId }); + } catch (error) { + clearTimeout(timeout); + this.pendingLists.delete(requestId); + reject(toError(error)); + } + }); + } + send(to, options) { + let socket; + try { + socket = this.requireActiveSocket(); + } catch (error) { + return Promise.reject(toError(error)); + } + const messageId = options.messageId ?? randomUUID2(); + if (this.pendingSends.has(messageId)) { + return Promise.resolve({ + id: messageId, + accepted: false, + delivered: false, + code: "DUPLICATE_MESSAGE_ID", + reason: `Message ID ${messageId} is already pending` + }); + } + const message = { + id: messageId, + timestamp: Date.now(), + replyTo: options.replyTo, + expectsReply: options.expectsReply, + content: { + text: options.text, + attachments: options.attachments + } + }; + try { + this.outbox?.enqueue(to, message); + } catch (error) { + return Promise.reject(toError(error)); + } + return new Promise((resolve4, reject) => { + const wrappedResolve = (result) => { + clearTimeout(timeout); + resolve4(result); + }; + const wrappedReject = (error) => { + clearTimeout(timeout); + reject(error); + }; + const timeout = setTimeout(() => { + if (this.pendingSends.has(messageId)) { + this.pendingSends.delete(messageId); + wrappedReject(new Error("Send timeout")); + } + }, 1e4); + this.pendingSends.set(messageId, { + accepted: false, + resolve: wrappedResolve, + reject: wrappedReject + }); + try { + writeMessage(socket, { type: "send", to, message }); + } catch (error) { + clearTimeout(timeout); + this.pendingSends.delete(messageId); + reject(toError(error)); + } + }); + } + sendBossControl(to, envelopeValue) { + let socket; + try { + socket = this.requireActiveSocket(); + } catch (error) { + return Promise.reject(toError(error)); + } + let envelope; + try { + envelope = parseBossControlEnvelope2(envelopeValue); + } catch (error) { + return Promise.reject(toError(error)); + } + if (this.pendingBossControls.has(envelope.messageId)) { + return Promise.resolve({ + id: envelope.messageId, + accepted: false, + delivered: false, + code: "CONFLICTING_MESSAGE_ID", + reason: `Boss control message ID ${envelope.messageId} is already pending` + }); + } + return new Promise((resolve4, reject) => { + const timeout = setTimeout(() => { + if (!this.pendingBossControls.delete(envelope.messageId)) return; + reject(new Error("Boss control send timeout")); + }, 1e4); + const wrappedResolve = (result) => { + clearTimeout(timeout); + resolve4(result); + }; + const wrappedReject = (error) => { + clearTimeout(timeout); + reject(error); + }; + this.pendingBossControls.set(envelope.messageId, { accepted: false, resolve: wrappedResolve, reject: wrappedReject }); + try { + writeMessage(socket, { type: "boss_control_send", to, envelope }); + } catch (error) { + this.pendingBossControls.delete(envelope.messageId); + wrappedReject(toError(error)); + } + }); + } + acknowledgeMessage(deliveryId) { + return this.writeControlMessage({ type: "message_received", deliveryId }); + } + acknowledgeBossControl(deliveryId) { + return this.writeControlMessage({ type: "boss_control_received", deliveryId }); + } + rejectMessage(deliveryId, reason) { + return this.writeControlMessage({ type: "message_rejected", deliveryId, code: "CONFLICTING_MESSAGE_ID", reason }); + } + deferAsk(messageId) { + return this.sendAskControl("defer", messageId); + } + cancelAsk(messageId) { + return this.sendAskControl("cancel", messageId); + } + sendAskControl(action, messageId) { + const requestId = randomUUID2(); + return new Promise((resolve4) => { + const timeout = setTimeout(() => { + this.pendingAskControls.delete(requestId); + resolve4(false); + }, 2e3); + timeout.unref?.(); + this.pendingAskControls.set(requestId, { resolve: resolve4, timeout }); + if (!this.writeControlMessage({ type: action === "defer" ? "defer_ask" : "cancel_ask", requestId, messageId })) { + clearTimeout(timeout); + this.pendingAskControls.delete(requestId); + resolve4(false); + } + }); + } + writeControlMessage(message) { + if (this.disconnecting) { + return false; + } + const socket = this.socket; + if (!socket || !this._sessionId || socket.destroyed || socket.writableEnded || !socket.writable) { + return false; + } + try { + writeMessage(socket, message); + return true; + } catch { + return false; + } + } + replayOutbox() { + const socket = this.socket; + if (!socket || !this._sessionId || socket.destroyed || socket.writableEnded || !socket.writable) return; + for (const entry of this.outbox?.list() ?? []) { + if (this.pendingSends.has(entry.message.id)) continue; + try { + writeMessage(socket, { type: "send", to: entry.to, message: entry.message }); + } catch { + return; + } + } + } + updatePresence(updates) { + if (this.disconnecting) { + return; + } + const socket = this.socket; + if (!socket || !this._sessionId || socket.destroyed || socket.writableEnded || !socket.writable) { + return; + } + writeMessage(socket, { type: "presence", ...updates }); + } +}; + +// broker/spawn.ts +import { spawn } from "child_process"; +import { existsSync as existsSync2, readFileSync as readFileSync4, unlinkSync, writeFileSync as writeFileSync2 } from "fs"; +import { join as join3, dirname as dirname2, extname, basename } from "path"; +import { fileURLToPath } from "url"; +import { createRequire } from "module"; +import net2 from "net"; +import { randomUUID as randomUUID3 } from "crypto"; +import { + POLICY_SEMANTICS_HASH as POLICY_SEMANTICS_HASH2, + POLICY_SEMANTICS_VERSION as POLICY_SEMANTICS_VERSION2 +} from "@dataforxyz/agent-intercom-core"; +var INTERCOM_DIR = getIntercomDirPath(); +var EXTENSION_DIR = join3(dirname2(fileURLToPath(import.meta.url)), ".."); +var BROKER_PID = join3(INTERCOM_DIR, "broker.pid"); +var BROKER_SPAWN_LOCK = join3(INTERCOM_DIR, "broker.spawn.lock"); +function sleep(ms) { + return new Promise((resolve4) => setTimeout(resolve4, ms)); +} +function getTsxCliPath(extensionDir = EXTENSION_DIR) { + try { + const requireFromExtension = createRequire(import.meta.url); + const tsxMain = requireFromExtension.resolve("tsx"); + return join3(dirname2(tsxMain), "cli.mjs"); + } catch { + return join3(extensionDir, "node_modules", "tsx", "dist", "cli.mjs"); + } +} +function getBrokerEntryPath(moduleUrl = import.meta.url) { + const directory = dirname2(fileURLToPath(moduleUrl)); + const bundled = join3(directory, "broker.mjs"); + return existsSync2(bundled) ? bundled : join3(directory, "broker.ts"); +} +function getNodeExecutable(execPath = process.execPath, platform = process.platform) { + const executable = basename(execPath).toLowerCase(); + if (executable === "node" || executable === "node.exe") return execPath; + return platform === "win32" ? "node.exe" : "node"; +} +function quoteWindowsArg(value) { + return `"${value.replace(/"/g, '""')}"`; +} +function getWindowsHiddenLauncherPath(intercomDir = INTERCOM_DIR) { + return join3(intercomDir, "broker-launch.vbs"); +} +function usesDefaultBrokerCommand(brokerCommand, brokerArgs) { + return brokerCommand === "npx" && brokerArgs.length === 2 && brokerArgs[0] === "--no-install" && brokerArgs[1] === "tsx"; +} +function getWindowsBrokerCommandLine(brokerPath, extensionDir = EXTENSION_DIR, nodePath = process.execPath, brokerCommand = "npx", brokerArgs = ["--no-install", "tsx"]) { + if (usesDefaultBrokerCommand(brokerCommand, brokerArgs)) { + if (extname(brokerPath) === ".mjs") { + return [quoteWindowsArg(nodePath), quoteWindowsArg(brokerPath)].join(" "); + } + return [quoteWindowsArg(nodePath), quoteWindowsArg(getTsxCliPath(extensionDir)), quoteWindowsArg(brokerPath)].join(" "); + } + return [quoteWindowsArg(brokerCommand), ...brokerArgs.map(quoteWindowsArg), quoteWindowsArg(brokerPath)].join(" "); +} +function getWindowsHiddenLauncherScript(commandLine) { + return [ + 'Set WshShell = CreateObject("WScript.Shell")', + `WshShell.Run "${commandLine.replace(/"/g, '""')}", 0, False`, + "Set WshShell = Nothing", + "" + ].join("\r\n"); +} +function isBrokerHealthOkMessage(message, requestId) { + if (typeof message !== "object" || message === null || !("type" in message)) { + return false; + } + const response = message; + if (response.type !== "health_ok" || response.requestId !== requestId || response.protocol !== INTERCOM_PROTOCOL_NAME || response.version !== INTERCOM_PROTOCOL_VERSION || response.endpoint !== "local") return false; + const remoteAccess = response.remoteAccess; + if (typeof remoteAccess !== "object" || remoteAccess === null || Array.isArray(remoteAccess)) return false; + const contract = remoteAccess; + return contract.feature === "remote-access-v1" && contract.policySemanticsVersion === POLICY_SEMANTICS_VERSION2 && contract.policySemanticsHash === POLICY_SEMANTICS_HASH2; +} +function writeWindowsHiddenLauncher(commandLine, launcherPath = getWindowsHiddenLauncherPath()) { + ensureIntercomRuntimeDir(dirname2(launcherPath)); + writeFileSync2(launcherPath, getWindowsHiddenLauncherScript(commandLine), { + encoding: "utf-8", + mode: INTERCOM_RUNTIME_FILE_MODE + }); + restrictIntercomRuntimeFile(launcherPath); + return launcherPath; +} +function getBrokerLaunchSpec(brokerPath, brokerCommand, brokerArgs, extensionDir = EXTENSION_DIR, platform = process.platform, intercomDir = INTERCOM_DIR, nodePath = process.execPath) { + if (platform === "win32") { + const launcherPath = getWindowsHiddenLauncherPath(intercomDir); + return { + kind: "windows-launcher", + command: "wscript.exe", + args: [launcherPath], + launcherPath, + launcherCommandLine: getWindowsBrokerCommandLine(brokerPath, extensionDir, nodePath, brokerCommand, brokerArgs) + }; + } + if (usesDefaultBrokerCommand(brokerCommand, brokerArgs)) { + if (extname(brokerPath) === ".mjs") { + return { + kind: "direct", + command: nodePath, + args: [brokerPath] + }; + } + return { + kind: "direct", + command: nodePath, + args: [getTsxCliPath(extensionDir), brokerPath] + }; + } + return { + kind: "direct", + command: brokerCommand, + args: [...brokerArgs, brokerPath] + }; +} +function getBrokerSpawnOptions(extensionDir = EXTENSION_DIR, env = process.env) { + return { + detached: true, + stdio: "ignore", + cwd: extensionDir, + env: { ...env, PI_CODING_AGENT_DIR: getAgentDirPath(env), NODE_NO_WARNINGS: "1" }, + windowsHide: true + }; +} +function toError2(error) { + return error instanceof Error ? error : new Error(String(error)); +} +async function spawnBrokerIfNeeded(brokerCommand, brokerArgs) { + ensureIntercomRuntimeDir(INTERCOM_DIR); + if (await isBrokerRunning()) { + return; + } + const ownsLock = acquireSpawnLock(); + if (!ownsLock) { + await waitForBroker(); + return; + } + try { + if (await isBrokerRunning()) { + return; + } + if (await checkBrokerHealth() === "incompatible") { + await stopBrokerProcess(); + } + const brokerPath = getBrokerEntryPath(); + const launch = getBrokerLaunchSpec( + brokerPath, + brokerCommand, + brokerArgs, + EXTENSION_DIR, + process.platform, + INTERCOM_DIR, + getNodeExecutable() + ); + if (launch.kind === "windows-launcher") { + writeWindowsHiddenLauncher(launch.launcherCommandLine, launch.launcherPath); + } + const child = spawn(launch.command, launch.args, getBrokerSpawnOptions()); + child.unref(); + await new Promise((resolve4, reject) => { + const cleanup = () => { + child.off("error", onError); + child.off("exit", onExit); + }; + const onError = (error) => { + cleanup(); + reject(new Error(`Failed to spawn intercom broker: ${error.message}`, { cause: error })); + }; + const onExit = (code, signal) => { + if (launch.kind === "windows-launcher" && code === 0 && signal === null) { + return; + } + cleanup(); + if (signal) { + reject(new Error(`Intercom broker exited before startup with signal ${signal}`)); + return; + } + reject(new Error(`Intercom broker exited before startup with code ${code ?? "unknown"}`)); + }; + child.once("error", onError); + child.once("exit", onExit); + waitForBroker().then(() => { + cleanup(); + resolve4(); + }, (error) => { + cleanup(); + reject(toError2(error)); + }); + }); + } finally { + releaseSpawnLock(); + } +} +async function stopBrokerProcess(pidFile = BROKER_PID, timeoutMs = 3e3) { + if (!existsSync2(pidFile)) return; + let pid; + try { + pid = Number.parseInt(readFileSync4(pidFile, "utf-8").trim(), 10); + } catch { + return; + } + if (!Number.isSafeInteger(pid) || pid <= 0 || pid === process.pid) return; + try { + process.kill(pid, "SIGTERM"); + } catch { + return; + } + const startedAt = Date.now(); + while (Date.now() - startedAt < timeoutMs) { + try { + process.kill(pid, 0); + await sleep(50); + } catch { + return; + } + } + throw new Error(`Incompatible intercom broker ${pid} did not stop within ${timeoutMs}ms`); +} +async function isBrokerRunning() { + if (await checkSocketConnectable()) { + return true; + } + if (!existsSync2(BROKER_PID)) return false; + try { + const pid = parseInt(readFileSync4(BROKER_PID, "utf-8").trim(), 10); + if (!Number.isFinite(pid)) return false; + process.kill(pid, 0); + return checkSocketConnectable(); + } catch { + return false; + } +} +function connectToBrokerTarget2(target) { + return typeof target === "string" ? net2.connect(target) : net2.connect({ host: target.host, port: target.port }); +} +async function checkSocketConnectable() { + return await checkBrokerHealth() === "compatible"; +} +function checkBrokerHealth() { + return new Promise((resolve4) => { + let target; + try { + target = getBrokerConnectTarget(); + } catch { + resolve4("unreachable"); + return; + } + const socket = connectToBrokerTarget2(target); + const requestId = randomUUID3(); + const expectedStateId = typeof target === "string" ? void 0 : target.stateId; + let settled = false; + const finish = (health) => { + if (settled) { + return; + } + settled = true; + clearTimeout(timeout); + socket.off("connect", onConnect); + socket.off("error", onError); + socket.off("data", reader); + socket.destroy(); + resolve4(health); + }; + const onConnect = () => { + try { + writeMessage(socket, { + type: "health", + requestId, + ...expectedStateId ? { stateId: expectedStateId } : {} + }); + } catch { + finish("unreachable"); + } + }; + const onError = () => finish("unreachable"); + const reader = createMessageReader((message) => { + if (isBrokerHealthOkMessage(message, requestId)) { + finish("compatible"); + return; + } + if (typeof message === "object" && message !== null && "type" in message && message.type === "health_ok" && "requestId" in message && message.requestId === requestId) { + finish("incompatible"); + return; + } + finish("unreachable"); + }, () => finish("unreachable")); + socket.on("connect", onConnect); + socket.on("error", onError); + socket.on("data", reader); + const timeout = setTimeout(() => finish("unreachable"), 1e3); + }); +} +function acquireSpawnLock() { + const maxRetries = 5; + for (let attempt = 0; attempt < maxRetries; attempt++) { + try { + writeFileSync2(BROKER_SPAWN_LOCK, `${process.pid} +${Date.now()} +`, { + flag: "wx", + mode: INTERCOM_RUNTIME_FILE_MODE + }); + restrictIntercomRuntimeFile(BROKER_SPAWN_LOCK); + return true; + } catch (error) { + if (!(error instanceof Error) || error.code !== "EEXIST") { + throw error; + } + if (isSpawnLockStale()) { + try { + unlinkSync(BROKER_SPAWN_LOCK); + } catch { + } + continue; + } + return false; + } + } + return false; +} +function isSpawnLockStale() { + if (!existsSync2(BROKER_SPAWN_LOCK)) { + return false; + } + try { + const [pidLine = "", createdAtLine = "0"] = readFileSync4(BROKER_SPAWN_LOCK, "utf-8").trim().split("\n"); + const pid = Number.parseInt(pidLine, 10); + const createdAt = Number.parseInt(createdAtLine, 10); + const ageMs = Date.now() - createdAt; + if (Number.isFinite(pid)) { + try { + process.kill(pid, 0); + } catch { + return true; + } + } + return !Number.isFinite(createdAt) || ageMs > 1e4; + } catch { + return true; + } +} +function releaseSpawnLock() { + try { + unlinkSync(BROKER_SPAWN_LOCK); + } catch { + } +} +async function waitForBroker(timeoutMs = 5e3) { + const start = Date.now(); + while (Date.now() - start < timeoutMs) { + if (await checkSocketConnectable()) { + return; + } + await sleep(100); + } + throw new Error("Broker failed to start within timeout"); +} + +// config.ts +import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs"; +import { join as join4, resolve as resolve2 } from "path"; +import { homedir as homedir2 } from "os"; +var DEFAULT_ASK_TIMEOUT_MS = 45 * 1e3; +var MAX_ASK_TIMEOUT_MS = 120 * 1e3; +function validateAskTimeoutMs(value, name = "timeout_ms") { + if (!Number.isSafeInteger(value) || typeof value !== "number" || value <= 0) { + throw new Error(`${name} must be a positive integer number of milliseconds`); + } + if (value > MAX_ASK_TIMEOUT_MS) { + throw new Error(`${name} must be ${MAX_ASK_TIMEOUT_MS} ms or less; use intercom_send plus intercom_pending for longer-running work`); + } + return value; +} +function getAskTimeoutMs() { + const raw = process.env.PI_INTERCOM_ASK_TIMEOUT_MS; + if (raw === void 0 || raw.trim() === "") { + return DEFAULT_ASK_TIMEOUT_MS; + } + const value = Number(raw); + return validateAskTimeoutMs(value, "PI_INTERCOM_ASK_TIMEOUT_MS"); +} +function getConfigPath() { + const agentDir = process.env.PI_CODING_AGENT_DIR ? resolve2(process.env.PI_CODING_AGENT_DIR) : join4(homedir2(), ".pi", "agent"); + return join4(agentDir, "intercom", "opencode-config.json"); +} +var defaults = { + brokerCommand: "npx", + brokerArgs: ["--no-install", "tsx"], + enabled: true +}; +function loadConfig() { + const configPath = getConfigPath(); + if (!existsSync3(configPath)) { + return { ...defaults }; + } + try { + const raw = readFileSync5(configPath, "utf-8"); + const parsed = JSON.parse(raw); + if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) { + throw new Error("Config must be a JSON object"); + } + const parsedConfig = parsed; + const config = { ...defaults }; + if (Object.hasOwn(parsedConfig, "brokerCommand")) { + if (typeof parsedConfig.brokerCommand !== "string") { + throw new Error(`"brokerCommand" must be a string`); + } + const brokerCommand = parsedConfig.brokerCommand.trim(); + if (!brokerCommand) { + throw new Error(`"brokerCommand" must not be empty`); + } + config.brokerCommand = brokerCommand; + } + if (Object.hasOwn(parsedConfig, "brokerArgs")) { + if (!Array.isArray(parsedConfig.brokerArgs)) { + throw new Error(`"brokerArgs" must be an array`); + } + const brokerArgs = []; + for (const arg of parsedConfig.brokerArgs) { + if (typeof arg !== "string") { + throw new Error(`"brokerArgs" items must be strings`); + } + brokerArgs.push(arg); + } + config.brokerArgs = brokerArgs; + } + if (Object.hasOwn(parsedConfig, "enabled")) { + if (typeof parsedConfig.enabled !== "boolean") { + throw new Error(`"enabled" must be a boolean`); + } + config.enabled = parsedConfig.enabled; + } + return config; + } catch (error) { + console.error(`Failed to load intercom config at ${configPath}:`, error); + return { ...defaults }; + } +} + +// opencode/inbound-store.ts +import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs"; +import { dirname as dirname3, join as join5 } from "path"; +var EMPTY_STATE = { version: 1, records: {}, delivered: [] }; +var MAX_DELIVERED_IDS = 1e3; +function sanitizeSegment(value) { + return value.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase() || "opencode"; +} +function getOpenCodeInboundStatePath(sessionId, intercomDir = getIntercomDirPath()) { + return join5(intercomDir, `opencode-inbound-${sanitizeSegment(sessionId)}.json`); +} +function normalizeState(value) { + if (!value || typeof value !== "object" || Array.isArray(value)) return structuredClone(EMPTY_STATE); + const input = value; + if (input.version !== 1 || !input.records || typeof input.records !== "object" || Array.isArray(input.records)) { + return structuredClone(EMPTY_STATE); + } + return { + version: 1, + records: input.records, + delivered: Array.isArray(input.delivered) ? input.delivered.filter((id) => typeof id === "string").slice(-MAX_DELIVERED_IDS) : [] + }; +} +var DurableInboundStore = class { + path; + state; + constructor(path) { + this.path = path; + ensureIntercomRuntimeDir(dirname3(path)); + this.state = this.load(); + } + load() { + if (!existsSync4(this.path)) return structuredClone(EMPTY_STATE); + try { + return normalizeState(JSON.parse(readFileSync6(this.path, "utf8"))); + } catch { + return structuredClone(EMPTY_STATE); + } + } + save() { + writeDurableJson(this.path, this.state); + } + rememberDelivered(messageId) { + this.state.delivered = [...this.state.delivered.filter((id) => id !== messageId), messageId].slice(-MAX_DELIVERED_IDS); + } + enqueue(entry) { + const messageId = entry.message.id; + if (this.state.delivered.includes(messageId)) return "delivered"; + const existing = this.state.records[messageId]; + if (existing) return existing.injected ? "injected" : "pending"; + this.state.records[messageId] = { entry, injected: false }; + this.save(); + return "new"; + } + pendingInjection() { + return Object.values(this.state.records).filter((record) => !record.injected).map((record) => record.entry); + } + unresolvedAsks() { + return Object.values(this.state.records).filter((record) => record.entry.message.expectsReply).map((record) => record.entry); + } + retainedEntries() { + return Object.values(this.state.records).map((record) => record.entry); + } + markInjected(messageId) { + const record = this.state.records[messageId]; + if (!record) return; + if (record.entry.message.expectsReply) { + record.injected = true; + } else { + delete this.state.records[messageId]; + this.rememberDelivered(messageId); + } + this.save(); + } + markReplied(messageId) { + delete this.state.records[messageId]; + this.rememberDelivered(messageId); + this.save(); + } +}; + +// opencode/team.ts +import { readFile } from "node:fs/promises"; +import { join as join6 } from "node:path"; +var LIVE_STATES = /* @__PURE__ */ new Set(["provisioning", "running", "idle", "needs_attention", "stopping"]); +var stringValue = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0; +var connectedTo = (sessions, target) => { + const normalized = target.toLowerCase(); + return sessions.some((session) => session.id === target || session.name?.toLowerCase() === normalized); +}; +async function readWorkers(agentDir) { + try { + const parsed = JSON.parse(await readFile(join6(agentDir, "intercom", "orchestrator", "workers.json"), "utf8")); + return Array.isArray(parsed.workers) ? parsed.workers : []; + } catch { + return []; + } +} +async function resolveIntercomTeam(input) { + const env = input.env ?? process.env; + const workers = await readWorkers(input.agentDir ?? getAgentDirPath()); + const workerId = stringValue(env.AGENT_INTERCOM_WORKER_ID); + const runId = stringValue(env.AGENT_INTERCOM_RUN_ID); + const current = workerId ? workers.find((worker) => stringValue(worker.id) === workerId && (!runId || stringValue(worker.runId) === runId)) : void 0; + const managerTarget = stringValue(current?.managerSessionId) ?? stringValue(env.AGENT_INTERCOM_MANAGER_TARGET) ?? stringValue(env.AGENT_INTERCOM_MANAGER_SESSION_ID); + const teamId = managerTarget ?? input.selfId; + const coworkers = workers.filter((worker) => worker.owned === true).filter((worker) => stringValue(worker.managerSessionId) === teamId).filter((worker) => LIVE_STATES.has(stringValue(worker.state) ?? "")).filter((worker) => stringValue(worker.id) !== workerId).map((worker) => { + const id = stringValue(worker.id); + if (!id) return void 0; + const target = stringValue(worker.intercomTarget) ?? id; + return { id, target, ...stringValue(worker.harness) ? { harness: stringValue(worker.harness) } : {}, ...stringValue(worker.role) ? { role: stringValue(worker.role) } : {}, ...stringValue(worker.state) ? { state: stringValue(worker.state) } : {}, connected: connectedTo(input.sessions, target) }; + }).filter((member) => Boolean(member)); + return { teamId, self: { id: input.selfId, ...workerId ? { workerId } : {}, isManager: !managerTarget }, manager: managerTarget ? { target: managerTarget, connected: connectedTo(input.sessions, managerTarget) } : { target: input.selfId, connected: true }, coworkers }; +} +function formatIntercomTeam(team) { + const lines = [`Manager: ${team.manager ? `${team.manager.target} [${team.manager.connected ? "connected" : "not connected"}]` : "unknown"}`, `You: ${team.self.id}${team.self.isManager ? " [manager]" : ""}`]; + if (!team.coworkers.length) lines.push("Coworkers: none"); + else { + lines.push("Coworkers:"); + for (const coworker of team.coworkers) { + const metadata = [coworker.harness, coworker.role, coworker.state].filter(Boolean).join(", "); + lines.push(`- ${coworker.id} target=${coworker.target}${metadata ? ` (${metadata})` : ""} [${coworker.connected ? "connected" : "not connected"}]`); + } + } + return lines.join("\n"); +} + +// opencode/runtime.ts +function matchesPendingSender(entry, to) { + return entry.from.id === to || entry.from.name?.toLowerCase() === to.toLowerCase() || entry.from.id.startsWith(to); +} +function selectPendingAsk(entries, to, which) { + const sorted = [...entries].sort((a, b) => a.receivedAt - b.receivedAt); + if (sorted.length === 0) throw new Error("No matching pending ask. Call intercom_pending to inspect unresolved asks."); + const matches = to ? sorted.filter((entry) => matchesPendingSender(entry, to)) : sorted; + if (matches.length === 0) throw new Error(`No pending ask from "${to}".`); + if (matches.length === 1) return matches[0]; + if (!to && new Set(matches.map((entry) => entry.from.id)).size > 1) { + throw new Error("Multiple pending asks \u2014 specify `to` using a sender from intercom_pending."); + } + if (!which) { + const sender = to ? ` from "${to}"` : ""; + throw new Error(`Multiple pending asks${sender} \u2014 specify \`which\` as \`oldest\` or \`latest\`.`); + } + return which === "oldest" ? matches[0] : matches[matches.length - 1]; +} +function pendingSelector(entries, entry) { + const sameSender = entries.filter((candidate) => candidate.from.id === entry.from.id); + if (sameSender.length <= 1) return void 0; + const index = sameSender.findIndex((candidate) => candidate.message.id === entry.message.id); + if (index === 0) return "oldest"; + if (index === sameSender.length - 1) return "latest"; + return "queued"; +} +function publicPendingEntry(entry, selector) { + return { + from: { + id: entry.from.id, + name: entry.from.name, + origin: entry.from.origin ?? "local", + ...entry.from.remoteHostId ? { remote_host_id: entry.from.remoteHostId } : {}, + ...entry.from.parentSessionId ? { parent_session_id: entry.from.parentSessionId } : {}, + ...entry.from.generation ? { generation: entry.from.generation } : {} + }, + received_at: entry.receivedAt, + read: entry.read, + text: entry.message.content.text, + attachments: entry.message.content.attachments, + expects_reply: entry.message.expectsReply, + ...selector ? { selector } : {} + }; +} +function shortHash(value) { + return createHash2("sha256").update(value).digest("hex").slice(0, 8); +} +function buildOpenCodeRuntimeIdentity(env = process.env, cwd = env.PWD || processCwd(), pid = process.pid) { + const sessionId = env.OPENCODE_INTERCOM_SESSION_ID?.trim() || `opencode-${pid}-${shortHash(cwd)}`; + const cwdName = basename2(cwd) || "workspace"; + const name = env.OPENCODE_INTERCOM_NAME?.trim() || env.OPENCODE_PEER_NAME?.trim() || `opencode-${cwdName}-${pid}`; + return { + sessionId, + name, + cwd, + model: env.OPENCODE_INTERCOM_MODEL?.trim() || env.OPENCODE_MODEL?.trim() || "opencode", + startedAt: Date.now() + }; +} +function formatAttachments(attachments) { + if (!attachments?.length) return ""; + return attachments.map((attachment) => { + if (attachment.language) { + return ` + +--- +Attachment: ${attachment.name} +~~~${attachment.language} +${attachment.content} +~~~`; + } + return ` + +--- +Attachment: ${attachment.name} +${attachment.content}`; + }).join(""); +} +function resolveSessionTarget(sessions, nameOrId) { + const byId = sessions.find((session) => session.id === nameOrId); + if (byId) return byId.id; + const lowerName = nameOrId.toLowerCase(); + const byName = sessions.filter((session) => session.name?.toLowerCase() === lowerName); + if (byName.length > 1) { + throw new Error(`Multiple sessions named "${nameOrId}" are connected. Use the session ID instead.`); + } + if (byName[0]) return byName[0].id; + if (nameOrId.length >= 4) { + const byPrefix = sessions.filter((session) => session.id.startsWith(nameOrId)); + if (byPrefix.length > 1) { + throw new Error(`Multiple sessions match the ID prefix "${nameOrId}". Use the full session ID or a unique name.`); + } + if (byPrefix[0]) return byPrefix[0].id; + } + return null; +} +function formatSessionDisplay(session) { + const name = session.name || session.id; + return session.origin === "remote" ? `${name} [remote:${session.remoteHostId || "unknown-host"}]` : name; +} +function formatSessionList(sessions, currentSessionId, currentCwd) { + if (!sessions.length) return "No intercom sessions connected."; + return sessions.map((session) => { + const tags = [ + session.id === currentSessionId ? "self" : void 0, + session.cwd === currentCwd ? "same cwd" : void 0, + session.status + ].filter((tag) => Boolean(tag)); + const suffix = tags.length ? ` [${tags.join(", ")}]` : ""; + return `- ${formatSessionDisplay(session)} (${session.id.slice(0, 8)}) - ${session.cwd} (${session.model})${suffix}`; + }).join("\n"); +} +function detectGitRoot(cwd) { + const result = spawnSync("git", ["rev-parse", "--show-toplevel"], { + cwd, + encoding: "utf8", + stdio: ["ignore", "pipe", "ignore"] + }); + if (result.status !== 0) return null; + return result.stdout.trim() || null; +} +function textResult(text, structuredContent, isError = false) { + return { + content: [{ type: "text", text }], + ...structuredContent ? { structuredContent } : {}, + ...isError ? { isError: true } : {} + }; +} +var OpenCodeIntercomRuntime = class { + client = null; + connectPromise = null; + reconnectTimer = null; + reconnectAttempt = 0; + reconnectEnabled = true; + identity; + unread = []; + unresolvedAsks = /* @__PURE__ */ new Map(); + replyWaiters = /* @__PURE__ */ new Map(); + onInboundMessage; + onConnectionState; + inboundStore; + clientFactory; + prepareConnection; + reconnectDelays; + onInboundActivity; + constructor(identity, cwd, onInboundMessage, inboundStore, options = {}) { + this.identity = identity ?? buildOpenCodeRuntimeIdentity(process.env, cwd); + this.onInboundMessage = onInboundMessage; + this.clientFactory = options.clientFactory ?? (() => new IntercomClient()); + this.prepareConnection = options.prepareConnection ?? (async () => { + const config = loadConfig(); + if (!config.enabled) throw new Error("Intercom disabled"); + await spawnBrokerIfNeeded(config.brokerCommand, config.brokerArgs); + }); + this.reconnectDelays = options.reconnectDelays?.length ? options.reconnectDelays : [250, 500, 1e3, 2e3, 5e3]; + this.onInboundActivity = options.onInboundActivity; + this.inboundStore = inboundStore ?? new DurableInboundStore( + process.env.OPENCODE_INTERCOM_INBOUND_STATE?.trim() || getOpenCodeInboundStatePath(this.identity.sessionId) + ); + this.unread = this.inboundStore.retainedEntries(); + for (const entry of this.inboundStore.unresolvedAsks()) this.unresolvedAsks.set(entry.message.id, entry); + } + getIdentity() { + return this.identity; + } + setConnectionStateHandler(handler) { + this.onConnectionState = handler; + } + async connect() { + this.reconnectEnabled = true; + this.clearReconnectTimer(); + if (this.client?.isConnected()) return this.client; + if (this.connectPromise) return this.connectPromise; + this.connectPromise = this.connectOnce(); + try { + return await this.connectPromise; + } finally { + this.connectPromise = null; + } + } + async connectOnce() { + await this.prepareConnection(); + const client = this.clientFactory(); + client.on("message", (from, message, deliveryId) => { + this.handleIncomingMessage(from, message, deliveryId); + }); + client.on("disconnected", (error) => { + for (const waiter of this.replyWaiters.values()) { + clearTimeout(waiter.timeout); + waiter.cleanup?.(); + waiter.reject(new Error(`Disconnected while waiting for reply: ${error.message}`, { cause: error })); + } + this.replyWaiters.clear(); + if (this.client === client) this.client = null; + this.onConnectionState?.(false, error); + this.scheduleReconnect(); + }); + await client.connect({ + name: this.identity.name, + cwd: this.identity.cwd, + model: this.identity.model, + pid: process.pid, + startedAt: this.identity.startedAt, + lastActivity: Date.now(), + status: "idle" + }, this.identity.sessionId); + this.client = client; + this.reconnectAttempt = 0; + this.onConnectionState?.(true); + for (const entry of this.inboundStore.pendingInjection()) { + void Promise.resolve(this.onInboundMessage?.(entry)).catch((error) => { + console.error("Failed to replay durable inbound intercom message:", error); + }); + } + return client; + } + scheduleReconnect() { + if (!this.reconnectEnabled || this.reconnectTimer) return; + const delay = this.reconnectDelays[Math.min(this.reconnectAttempt, this.reconnectDelays.length - 1)]; + this.reconnectTimer = setTimeout(() => { + this.reconnectTimer = null; + void this.connect().then((client) => { + if (!client.isConnected()) { + this.reconnectAttempt += 1; + this.scheduleReconnect(); + } + }).catch((error) => { + this.reconnectAttempt += 1; + this.onConnectionState?.(false, error instanceof Error ? error : new Error(String(error))); + this.scheduleReconnect(); + }); + }, delay); + this.reconnectTimer.unref?.(); + } + clearReconnectTimer() { + if (!this.reconnectTimer) return; + clearTimeout(this.reconnectTimer); + this.reconnectTimer = null; + } + async disconnect() { + this.reconnectEnabled = false; + this.clearReconnectTimer(); + if (this.connectPromise) { + try { + await this.connectPromise; + } catch { + } + } + const client = this.client; + this.client = null; + if (client) await client.disconnect(); + } + handleIncomingMessage(from, message, deliveryId) { + const waiter = this.replyWaiters.get(message.replyTo ?? ""); + if (waiter) { + const senderTarget = from.name || from.id; + const fromMatches = senderTarget.toLowerCase() === waiter.from.toLowerCase() || from.id === waiter.from; + if (fromMatches) { + void Promise.resolve(this.onInboundActivity?.(from, message)).catch(() => void 0); + this.replyWaiters.delete(waiter.replyTo); + clearTimeout(waiter.timeout); + waiter.cleanup?.(); + waiter.resolve(message); + this.client?.acknowledgeMessage(deliveryId); + return; + } + } + const entry = { from, message, deliveryId, receivedAt: Date.now(), read: false }; + const disposition = this.inboundStore.enqueue(entry); + if (disposition !== "new") { + this.client?.acknowledgeMessage(deliveryId); + return; + } + void Promise.resolve(this.onInboundActivity?.(from, message)).catch(() => void 0); + this.unread.push(entry); + if (message.expectsReply) { + this.unresolvedAsks.set(message.id, entry); + } + this.client?.acknowledgeMessage(deliveryId); + void Promise.resolve(this.onInboundMessage?.(entry)).catch((error) => { + console.error("Failed to inject inbound intercom message:", error); + }); + } + markInboundInjected(messageId) { + this.inboundStore.markInjected(messageId); + } + markInboundReplied(messageId) { + this.inboundStore.markReplied(messageId); + this.unresolvedAsks.delete(messageId); + } + waitForReply(from, replyTo, timeoutMs = getAskTimeoutMs(), signal) { + return new Promise((resolve4, reject) => { + if (signal?.aborted) { + reject(new Error("intercom_ask cancelled")); + return; + } + let timeout; + const cleanup = () => { + clearTimeout(timeout); + signal?.removeEventListener("abort", onAbort); + }; + const onAbort = () => { + this.replyWaiters.delete(replyTo); + cleanup(); + void this.client?.cancelAsk(replyTo); + reject(new Error("intercom_ask cancelled")); + }; + timeout = setTimeout(() => { + this.replyWaiters.delete(replyTo); + void this.client?.deferAsk(replyTo); + signal?.removeEventListener("abort", onAbort); + reject(new Error(`No reply from "${from}" within ${Math.round(timeoutMs / 1e3)} seconds`)); + }, timeoutMs); + signal?.addEventListener("abort", onAbort, { once: true }); + this.replyWaiters.set(replyTo, { from, replyTo, resolve: resolve4, reject, timeout, cleanup }); + }); + } + async resolveTarget(to) { + const client = await this.connect(); + const sessions = await client.listSessions(); + return resolveSessionTarget(sessions, to) ?? to; + } + async whoami() { + const client = await this.connect(); + const sessionId = client.sessionId ?? this.identity.sessionId; + return textResult( + `session_id: ${sessionId} +name: ${this.identity.name} +cwd: ${this.identity.cwd}`, + { session_id: sessionId, name: this.identity.name, cwd: this.identity.cwd, model: this.identity.model } + ); + } + async team() { + const client = await this.connect(); + const sessions = await client.listSessions(); + const team = await resolveIntercomTeam({ selfId: client.sessionId ?? this.identity.sessionId, sessions }); + return textResult(formatIntercomTeam(team), team); + } + async status() { + const client = await this.connect(); + const sessions = await client.listSessions(); + return textResult( + `Connected: ${client.isConnected() ? "Yes" : "No"} +Session ID: ${client.sessionId ?? "unknown"} +Active sessions: ${sessions.length} +Unread messages: ${this.unread.filter((entry) => !entry.read).length} +Pending asks: ${this.unresolvedAsks.size}`, + { + connected: client.isConnected(), + session_id: client.sessionId, + active_sessions: sessions.length, + unread_messages: this.unread.filter((entry) => !entry.read).length, + pending_asks: this.unresolvedAsks.size + } + ); + } + async list(scope = "machine", includeSelf = false) { + const client = await this.connect(); + let sessions = await client.listSessions(); + if (scope === "directory") { + sessions = sessions.filter((session) => session.cwd === this.identity.cwd); + } else if (scope === "repo") { + const currentRoot = detectGitRoot(this.identity.cwd); + sessions = currentRoot ? sessions.filter((session) => detectGitRoot(session.cwd) === currentRoot) : []; + } + if (!includeSelf) { + sessions = sessions.filter((session) => session.id !== client.sessionId); + } + return textResult(formatSessionList(sessions, client.sessionId, this.identity.cwd), { sessions }); + } + async sessions(includeSelf = false) { + const client = await this.connect(); + const sessions = await client.listSessions(); + return includeSelf ? sessions : sessions.filter((session) => session.id !== client.sessionId); + } + async setSummary(summary) { + const client = await this.connect(); + client.updatePresence({ status: summary.trim() || "idle" }); + return textResult("Summary updated.", { ok: true, summary }); + } + async send(to, message, attachments, replyTo) { + const client = await this.connect(); + const sendTo = await this.resolveTarget(to); + const result = await client.send(sendTo, { text: message, attachments, replyTo }); + if (!result.delivered) { + return textResult(`Message to "${to}" was not delivered: ${result.reason ?? "Session may not exist or has disconnected."}`, { ok: false, accepted: result.accepted, delivered: false, message_id: result.id, delivery_id: result.deliveryId, code: result.code, reason: result.reason }, true); + } + if (replyTo) this.markInboundReplied(replyTo); + return textResult(`Message sent to ${to}.`, { ok: true, accepted: result.accepted, delivered: true, message_id: result.id, delivery_id: result.deliveryId, to }); + } + async ask(to, message, attachments, timeoutMs = getAskTimeoutMs(), signal) { + const client = await this.connect(); + const sendTo = await this.resolveTarget(to); + const questionId = randomUUID4(); + const replyPromise = this.waitForReply(sendTo, questionId, timeoutMs, signal); + void replyPromise.catch(() => void 0); + try { + const result = await client.send(sendTo, { + messageId: questionId, + text: message, + attachments, + expectsReply: true + }); + if (!result.delivered) { + this.replyWaiters.get(questionId)?.reject(new Error(result.reason ?? "Session may not exist or has disconnected.")); + this.replyWaiters.delete(questionId); + client.cancelAsk(questionId); + return textResult(`Message to "${to}" was not delivered: ${result.reason ?? "Session may not exist or has disconnected."}`, { ok: false, message_id: result.id, reason: result.reason }, true); + } + const reply = await replyPromise; + const replyText = `${reply.content.text}${formatAttachments(reply.content.attachments)}`; + return textResult(`Reply from ${to}: +${replyText}`, { ok: true, message_id: result.id, reply }); + } catch (error) { + client.cancelAsk(questionId); + return textResult(error instanceof Error ? error.message : String(error), { ok: false }, true); + } + } + async pending(markRead = false) { + const unreadMessages = this.unread.filter((entry) => !entry.read); + if (markRead) { + for (const entry of unreadMessages) entry.read = true; + } + const pendingAsks = Array.from(this.unresolvedAsks.values()).sort((a, b) => a.receivedAt - b.receivedAt); + const lines = [ + unreadMessages.length ? unreadMessages.map((entry) => `- ${formatSessionDisplay(entry.from)}: ${entry.message.content.text}${formatAttachments(entry.message.content.attachments)}`).join("\n") : "No unread messages.", + pendingAsks.length ? ` +Pending asks: +${pendingAsks.map((entry) => { + const selector = pendingSelector(pendingAsks, entry); + return `- ${formatSessionDisplay(entry.from)}${selector ? ` [${selector}]` : ""}: ${entry.message.content.text}`; + }).join("\n")}` : "" + ].filter(Boolean); + return textResult(lines.join("\n"), { + unread_messages: unreadMessages.map((entry) => publicPendingEntry(entry)), + pending_asks: pendingAsks.map((entry) => publicPendingEntry(entry, pendingSelector(pendingAsks, entry))) + }); + } + async reply(message, to, which) { + let target; + try { + target = selectPendingAsk(Array.from(this.unresolvedAsks.values()), to, which); + } catch (error) { + return textResult(error instanceof Error ? error.message : String(error), { ok: false }, true); + } + const result = await this.send(target.from.id, message, void 0, target.message.id); + if (!result.isError) { + this.unresolvedAsks.delete(target.message.id); + } + return result; + } +}; + +// opencode/health.ts +import { mkdirSync as mkdirSync3 } from "node:fs"; +import { dirname as dirname4 } from "node:path"; +function normalizeOpenCodeSessionStatus(value) { + if (typeof value === "string" && value.trim()) return value; + if (value && typeof value === "object" && typeof value.type === "string") { + return value.type; + } + return "active"; +} +var OpenCodePeerHealthReporter = class { + path; + health; + constructor(input) { + this.path = input.path?.trim() || void 0; + this.health = { + version: 1, + runId: input.runId?.trim() || "standalone", + workerId: input.workerId?.trim() || input.intercomSessionId, + intercomSessionId: input.intercomSessionId, + serverUrl: input.serverUrl, + directory: input.directory, + pid: input.pid ?? process.pid, + connected: false, + ready: false, + status: "starting", + updatedAt: Date.now() + }; + this.write(); + } + update(patch) { + this.health = { + ...this.health, + ...patch, + updatedAt: Date.now() + }; + this.health.ready = this.health.connected && Boolean(this.health.openCodeSessionId) && !this.health.error; + this.write(); + return this.snapshot(); + } + snapshot() { + return structuredClone(this.health); + } + write() { + if (!this.path) return; + mkdirSync3(dirname4(this.path), { recursive: true, mode: 448 }); + writeDurableJson(this.path, this.health); + } +}; + +// opencode/fleet.ts +import { spawn as spawn2 } from "node:child_process"; +function isFleetManagementEnabled(env = process.env) { + const enabled = env.OPENCODE_INTERCOM_FLEET === "1" || env.OPENCODE_INTERCOM_FLEET === "true"; + if (!enabled) return false; + const ownedWorker = env.AGENT_INTERCOM_OWNED === "1"; + const allowNested = env.OPENCODE_INTERCOM_FLEET_ALLOW_NESTED === "1"; + return !ownedWorker || allowNested; +} +async function invokeAgentFleet(params, context, env = process.env) { + const command = env.AGENT_INTERCOM_FLEET_COMMAND?.trim() || "agent-intercom-fleet"; + const timeoutMs = Number(env.AGENT_INTERCOM_FLEET_TIMEOUT_MS || 12e4); + return new Promise((resolve4, reject) => { + const child = spawn2(command, [], { + cwd: context.cwd, + env, + stdio: ["pipe", "pipe", "pipe"] + }); + let stdout = ""; + let stderr = ""; + let settled = false; + let timer; + const finish = (error, value) => { + if (settled) return; + settled = true; + if (timer) clearTimeout(timer); + if (error) reject(error); + else resolve4(value); + }; + child.stdout.on("data", (chunk) => { + stdout += chunk; + }); + child.stderr.on("data", (chunk) => { + stderr += chunk; + }); + child.on("error", (error) => finish(new Error(`Could not start ${command}: ${error.message}`, { cause: error }))); + child.on("close", (code) => { + let response; + try { + response = JSON.parse(stdout.trim()); + } catch { + finish(new Error(`${command} returned invalid JSON: ${stderr.trim() || stdout.trim() || `exit ${code}`}`)); + return; + } + if (code !== 0 || response?.ok !== true) { + finish(new Error(response?.error || stderr.trim() || `${command} exited with ${code}`)); + return; + } + finish(void 0, response.result); + }); + child.stdin.end(JSON.stringify({ params, managerSessionId: context.managerSessionId, cwd: context.cwd })); + timer = setTimeout(() => { + child.kill("SIGKILL"); + finish(new Error(`${command} timed out after ${timeoutMs}ms`)); + }, Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : 12e4); + timer.unref?.(); + }); +} + +// opencode/control.ts +import { randomUUID as randomUUID5 } from "node:crypto"; +import { mkdirSync as mkdirSync4, readFileSync as readFileSync7, readdirSync, renameSync as renameSync3, rmSync, writeFileSync as writeFileSync3 } from "node:fs"; +import { join as join7 } from "node:path"; +var CONTROL_DIR_NAME = "opencode-control"; +function controlDir() { + const directory = join7(getIntercomDirPath(), CONTROL_DIR_NAME); + mkdirSync4(directory, { recursive: true, mode: 448 }); + return directory; +} +function safeSessionId(sessionId) { + return sessionId.replace(/[^a-zA-Z0-9._-]/g, "_"); +} +function responseName(sessionId, requestId) { + return `${safeSessionId(sessionId)}.${requestId}.response.json`; +} +function writeJsonAtomic(path, value) { + const temporary = `${path}.${process.pid}.${randomUUID5()}.tmp`; + writeFileSync3(temporary, JSON.stringify(value), { mode: 384 }); + restrictIntercomRuntimeFile(temporary); + renameSync3(temporary, path); + restrictIntercomRuntimeFile(path); +} +function startOpenCodeControlServer(options) { + const directory = controlDir(); + let processing = false; + const timer = setInterval(async () => { + if (processing) return; + processing = true; + try { + const files = readdirSync(directory).filter((file) => file.endsWith(".request.json")); + for (const file of files) { + const requestPath = join7(directory, file); + let request; + try { + request = JSON.parse(readFileSync7(requestPath, "utf8")); + } catch { + continue; + } + if (!request?.id || !request.sessionId || !options.acceptsSession(request.sessionId)) continue; + const responsePath = join7(directory, responseName(request.sessionId, request.id)); + let response; + try { + response = { ok: true, value: await options.handle(request.action) }; + } catch (error) { + response = { ok: false, error: error instanceof Error ? error.message : String(error) }; + } + writeJsonAtomic(responsePath, response); + rmSync(requestPath, { force: true }); + } + } finally { + processing = false; + } + }, 100); + timer.unref(); + return () => clearInterval(timer); +} + +// opencode/plugin.ts +var INJECT_LOG_PATH = "/tmp/intercom-inject.log"; +function resultText(result) { + const text = result.content.map((part) => part.text).join("\n"); + if (result.isError) { + throw new Error(text); + } + return text; +} +function listScope(value) { + if (value === void 0) return "machine"; + if (value === "machine" || value === "directory" || value === "repo") return value; + throw new Error('scope must be one of "machine", "directory", or "repo"'); +} +var OpenCodeIntercomPlugin = async ({ client, directory, serverUrl }) => { + let activeSessionID = process.env.OPENCODE_INTERCOM_TARGET_SESSION?.trim() || process.env.OPENCODE_SESSION_ID?.trim() || void 0; + let activeSessionStatus = "idle"; + const knownSessionIDs = /* @__PURE__ */ new Set(); + let flushingInjectQueue = false; + const pendingInjectQueue = []; + const deliveredMessageIDs = /* @__PURE__ */ new Set(); + let runtime; + let healthReporter; + const canUseTuiInjection = Boolean(process.stdin.isTTY || process.stdout.isTTY); + const debugInject = process.env.OPENCODE_INTERCOM_DEBUG === "1"; + const fleetManagementEnabled = isFleetManagementEnabled(); + let fleetHeartbeatRunning = false; + let fleetHeartbeat; + function logInject(step, details) { + if (!debugInject) { + return; + } + try { + appendFileSync(INJECT_LOG_PATH, `${JSON.stringify({ time: (/* @__PURE__ */ new Date()).toISOString(), step, ...details })} +`); + } catch { + } + } + function formatError(error) { + if (error instanceof Error) { + return { + name: error.name, + message: error.message, + stack: error.stack, + cause: error.cause + }; + } + return { value: error }; + } + async function logResult(step, result, details = {}) { + const responseBody = result.response ? await result.response.clone().text().catch(() => void 0) : void 0; + logInject(step, { + ...details, + ok: result.error === void 0, + status: result.response?.status, + data: result.data, + error: result.error, + responseBody + }); + } + function rememberBounded(values, value, limit = 4096) { + values.add(value); + while (values.size > limit) { + const oldest = values.values().next().value; + if (typeof oldest !== "string") break; + values.delete(oldest); + } + } + function setActiveSession(sessionID) { + if (typeof sessionID === "string" && sessionID.trim()) { + activeSessionID = sessionID; + rememberBounded(knownSessionIDs, sessionID); + healthReporter?.update({ openCodeSessionId: sessionID, status: activeSessionStatus }); + } + } + function messageMarker(messageID) { + return `[agent-intercom-message:${messageID}]`; + } + function formatInboundPrompt(entry) { + const from = formatSessionDisplay(entry.from); + const replyHint = entry.message.expectsReply ? "\n\nThis message expects a reply. Use intercom_reply with only your reply text while this turn is active. If you reply later, use intercom_pending plus the sender and oldest/latest selector." : ""; + return [ + `Incoming intercom message from ${from} (${entry.from.model}, ${entry.from.cwd}):`, + "", + entry.message.content.text + formatAttachments(entry.message.content.attachments), + replyHint, + messageMarker(entry.message.id) + ].join("\n"); + } + async function resolveActiveSessionID() { + if (activeSessionID) { + return activeSessionID; + } + const sessionList = await client.session.list({ query: { directory } }).catch((error) => { + logInject("session.list.error", { error: formatError(error) }); + return void 0; + }); + if (sessionList) { + await logResult("session.list", sessionList); + } + const sessions = sessionList?.data; + if (!sessions?.length) { + return void 0; + } + const latestSession = sessions.reduce((latest, session) => { + if (session.time.created > latest.time.created) { + return session; + } + if (session.time.created === latest.time.created && session.time.updated > latest.time.updated) { + return session; + } + return latest; + }); + setActiveSession(latestSession.id); + logInject("session.resolve", { sessionID: latestSession.id, sessionCount: sessions.length }); + return latestSession.id; + } + function enqueuePendingInject(entry, reason) { + if (deliveredMessageIDs.has(entry.message.id)) { + logInject("queue.skip_delivered", { reason, messageID: entry.message.id }); + return; + } + if (pendingInjectQueue.some((queued) => queued.entry.message.id === entry.message.id)) { + logInject("queue.skip_duplicate", { reason, messageID: entry.message.id }); + return; + } + pendingInjectQueue.push({ entry }); + logInject("queue.enqueue", { reason, messageID: entry.message.id, queueLength: pendingInjectQueue.length }); + } + function markDelivered(messageID, path) { + rememberBounded(deliveredMessageIDs, messageID); + runtime.markInboundInjected(messageID); + const queueIndex = pendingInjectQueue.findIndex((queued) => queued.entry.message.id === messageID); + if (queueIndex >= 0) { + pendingInjectQueue.splice(queueIndex, 1); + } + logInject("message.delivered", { messageID, path, queueLength: pendingInjectQueue.length }); + } + async function sessionAlreadyContainsMessage(sessionID, messageID) { + const marker = messageMarker(messageID); + const result = await client.session.messages({ + path: { id: sessionID }, + query: { directory, limit: 200 } + }).catch((error) => { + logInject("session.messages.error", { sessionID, messageID, error: formatError(error) }); + return void 0; + }); + const messages = result?.data; + if (!messages) return false; + return messages.some((message) => message.parts.some((part) => { + if (part.type !== "text") return false; + const metadata = part.metadata; + return metadata?.intercomMessageId === messageID || part.text.includes(marker); + })); + } + async function flushPendingInjectQueue(trigger) { + if (flushingInjectQueue || !pendingInjectQueue.length) { + return; + } + const sessionID = await resolveActiveSessionID(); + if (!sessionID) { + logInject("queue.flush.skip", { trigger, reason: "no_session_id", queueLength: pendingInjectQueue.length }); + return; + } + flushingInjectQueue = true; + logInject("queue.flush.start", { trigger, sessionID, queueLength: pendingInjectQueue.length }); + try { + while (pendingInjectQueue.length) { + const queued = pendingInjectQueue[0]; + const entry = queued.entry; + if (deliveredMessageIDs.has(entry.message.id)) { + pendingInjectQueue.shift(); + logInject("queue.flush.skip_delivered", { trigger, messageID: entry.message.id }); + continue; + } + const prompt = formatInboundPrompt(entry); + if (await sessionAlreadyContainsMessage(sessionID, entry.message.id)) { + markDelivered(entry.message.id, "session.messages.replay_dedupe"); + continue; + } + let result; + try { + result = await client.session.promptAsync({ + path: { id: sessionID }, + query: { directory }, + body: { + parts: [{ type: "text", text: prompt, metadata: { intercomMessageId: entry.message.id } }] + } + }); + } catch (error) { + logInject("queue.flush.promptAsync.throw", { + trigger, + sessionID, + messageID: entry.message.id, + error: formatError(error) + }); + break; + } + await logResult("queue.flush.promptAsync", result, { + trigger, + sessionID, + messageID: entry.message.id + }); + if (result.error !== void 0 || !result.response?.ok) { + break; + } + markDelivered(entry.message.id, "queue.flush.promptAsync"); + } + } finally { + logInject("queue.flush.end", { trigger, remaining: pendingInjectQueue.length }); + flushingInjectQueue = false; + } + } + async function injectInbound(entry) { + const from = formatSessionDisplay(entry.from); + const prompt = formatInboundPrompt(entry); + if (deliveredMessageIDs.has(entry.message.id)) { + logInject("inject.skip_delivered", { messageID: entry.message.id }); + return; + } + const busy = activeSessionStatus !== "idle"; + logInject("inject.start", { + messageID: entry.message.id, + from, + activeSessionID, + activeSessionStatus + }); + if (busy) { + enqueuePendingInject(entry, "session_busy_pre_tui"); + } + logInject("inject.mode", { + messageID: entry.message.id, + canUseTuiInjection, + busy + }); + try { + const toastResult = await client.tui.showToast({ + body: { + title: `Intercom from ${from}`, + message: entry.message.content.text.slice(0, 240), + variant: entry.message.expectsReply ? "warning" : "info", + duration: 8e3 + }, + query: { directory } + }); + await logResult("inject.toast", toastResult, { messageID: entry.message.id }); + } catch (error) { + logInject("inject.toast.throw", { messageID: entry.message.id, error: formatError(error) }); + } + if (canUseTuiInjection) { + try { + const appended = await client.tui.appendPrompt({ + body: { text: prompt }, + query: { directory } + }); + await logResult("inject.append", appended, { messageID: entry.message.id }); + if (appended.data === true) { + try { + const submitResult = await client.tui.submitPrompt({ query: { directory } }); + await logResult("inject.submit", submitResult, { messageID: entry.message.id }); + if (!busy) { + markDelivered(entry.message.id, "tui.submit"); + return; + } + } catch (error) { + logInject("inject.submit.throw", { messageID: entry.message.id, error: formatError(error) }); + } + } + } catch (error) { + logInject("inject.append.throw", { messageID: entry.message.id, error: formatError(error) }); + } + } else { + logInject("inject.tui_skipped", { messageID: entry.message.id, reason: "headless" }); + } + const sessionID = await resolveActiveSessionID(); + if (!sessionID) { + logInject("inject.no_session", { messageID: entry.message.id }); + return; + } + logInject("inject.session_target", { + messageID: entry.message.id, + sessionID, + activeSessionStatus, + busy + }); + try { + if (await sessionAlreadyContainsMessage(sessionID, entry.message.id)) { + markDelivered(entry.message.id, "session.messages.inject_dedupe"); + return; + } + const asyncResult = await client.session.promptAsync({ + path: { id: sessionID }, + query: { directory }, + body: { + parts: [{ type: "text", text: prompt, metadata: { intercomMessageId: entry.message.id } }] + } + }); + await logResult("inject.promptAsync", asyncResult, { messageID: entry.message.id, sessionID, busy }); + if (asyncResult.error === void 0 && asyncResult.response?.ok) { + markDelivered(entry.message.id, "session.promptAsync"); + } else { + enqueuePendingInject(entry, "prompt_async_error"); + } + } catch (error) { + logInject("inject.promptAsync.throw", { + messageID: entry.message.id, + sessionID, + error: formatError(error) + }); + enqueuePendingInject(entry, "prompt_async_throw"); + } + } + runtime = new OpenCodeIntercomRuntime(void 0, directory, injectInbound, void 0, { + onInboundActivity(from) { + if (!fleetManagementEnabled) return; + void invokeAgentFleet({ action: "renew", id: from.id }, { + managerSessionId: runtime.getIdentity().sessionId, + cwd: directory + }, { ...process.env, AGENT_INTERCOM_DISABLE_CLEANUP_TIMER: "1" }).catch(() => void 0); + } + }); + const runtimeIdentity = runtime.getIdentity(); + healthReporter = new OpenCodePeerHealthReporter({ + path: process.env.AGENT_INTERCOM_OPENCODE_HEALTH_PATH, + runId: process.env.AGENT_INTERCOM_RUN_ID, + workerId: process.env.AGENT_INTERCOM_WORKER_ID, + intercomSessionId: runtimeIdentity.sessionId, + serverUrl: serverUrl.toString(), + directory + }); + runtime.setConnectionStateHandler((connected, error) => { + healthReporter.update({ + connected, + status: connected ? activeSessionStatus : "reconnecting", + error: error?.message + }); + }); + void (async () => { + try { + await runtime.connect(); + healthReporter.update({ connected: true, status: activeSessionStatus, error: void 0 }); + await resolveActiveSessionID(); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + healthReporter.update({ connected: false, status: "error", error: message }); + console.error("Failed to start OpenCode intercom listener:", error); + } + })(); + if (activeSessionID) rememberBounded(knownSessionIDs, activeSessionID); + if (fleetManagementEnabled) { + fleetHeartbeat = setInterval(() => { + if (fleetHeartbeatRunning) return; + fleetHeartbeatRunning = true; + void invokeAgentFleet({ action: "_heartbeat" }, { + managerSessionId: runtimeIdentity.sessionId, + cwd: directory + }).then(async (result) => { + const requests = Array.isArray(result?.details?.checkpointRequests) ? result.details.checkpointRequests : []; + for (const request of requests) { + if (typeof request?.target !== "string" || typeof request?.message !== "string") continue; + await runtime.send(request.target, request.message); + } + }).catch((error) => { + logInject("fleet.heartbeat.error", { error: formatError(error) }); + }).finally(() => { + fleetHeartbeatRunning = false; + }); + }, 6e4); + fleetHeartbeat.unref?.(); + } + const stopControlServer = startOpenCodeControlServer({ + acceptsSession: (sessionID) => knownSessionIDs.has(sessionID), + async handle(action) { + if (action.type === "whoami") { + return runtime.getIdentity(); + } + if (action.type === "list") { + return runtime.sessions(false); + } + if (action.type === "send") { + if (typeof action.to !== "string" || typeof action.message !== "string" || !action.message.trim()) { + throw new Error("Invalid intercom send request."); + } + const result = await runtime.send(action.to, action.message); + if (result.isError) throw new Error(result.content.map((part) => part.text).join("\n")); + return result.structuredContent ?? { ok: true }; + } + throw new Error("Unsupported OpenCode intercom action."); + } + }); + return { + dispose: async () => { + if (fleetHeartbeat) clearInterval(fleetHeartbeat); + fleetHeartbeat = void 0; + stopControlServer(); + healthReporter.update({ connected: false, ready: false, status: "stopped" }); + await runtime.disconnect(); + }, + tool: { + ...fleetManagementEnabled ? { + agent_fleet: tool({ + description: "Create, inspect, adopt, stop, and clean up systemd-owned Pi, Codex, Claude, and OpenCode coworkers. Spawn/list results include direct Intercom targets; list/status default to this manager's workers. Enabled only for an explicitly configured primary OpenCode manager.", + args: { + action: tool.schema.string().describe("Fleet action: spawn, list, status, stop, cleanup, doctor, versions, update, logs, renew, forget, adopt, capabilities, profiles, models, variants, or config."), + id: tool.schema.string().optional().describe("Stable worker ID."), + harness: tool.schema.string().optional().describe("pi, codex, claude, or opencode."), + role: tool.schema.string().optional().describe("Worker role or configured role preset."), + task: tool.schema.string().optional().describe("Assignment or standing mandate."), + cwd: tool.schema.string().optional().describe("Worker working directory."), + profile: tool.schema.string().optional().describe("Configured launch profile."), + model: tool.schema.string().optional().describe("Harness model identifier."), + effort: tool.schema.string().optional().describe("Normalized effort or OpenCode model variant."), + instructions: tool.schema.string().optional().describe("Additional standing instructions."), + fresh: tool.schema.boolean().optional().describe("Start a fresh persistent session rather than resume this worker ID."), + all: tool.schema.boolean().optional().describe("Include workers owned by other manager sessions for list/status diagnostics."), + execute: tool.schema.boolean().optional().describe("Actually execute cleanup or updates; false previews."), + acknowledge: tool.schema.boolean().optional().describe("Manager acknowledgment required before deleting a stopped worker record."), + lines: tool.schema.number().optional().describe("Journal lines for logs.") + }, + async execute(args, context) { + setActiveSession(context.sessionID); + const result = await invokeAgentFleet(args, { + managerSessionId: runtimeIdentity.sessionId, + cwd: directory + }); + return resultText(result); + } + }) + } : {}, + intercom_whoami: tool({ + description: "Show this OpenCode session's intercom identity.", + args: {}, + async execute(_args, context) { + setActiveSession(context.sessionID); + return resultText(await runtime.whoami()); + } + }), + intercom_team: tool({ + description: "Show your current manager and the live coworkers owned by that manager. No arguments are required.", + args: {}, + async execute(_args, context) { + setActiveSession(context.sessionID); + return resultText(await runtime.team()); + } + }), + intercom_status: tool({ + description: "Show local intercom connection status and pending message counts.", + args: {}, + async execute(_args, context) { + setActiveSession(context.sessionID); + return resultText(await runtime.status()); + } + }), + intercom_list: tool({ + description: "List local Pi, Codex, Claude, and OpenCode intercom sessions.", + args: { + scope: tool.schema.string().optional().describe('Filter sessions: "machine", "directory", or "repo".'), + include_self: tool.schema.boolean().optional().describe("Include this OpenCode session in the result.") + }, + async execute(args, context) { + setActiveSession(context.sessionID); + return resultText(await runtime.list(listScope(args.scope), args.include_self ?? false)); + } + }), + intercom_set_summary: tool({ + description: "Publish a short discoverable status for this OpenCode session.", + args: { + summary: tool.schema.string().describe("Short status shown to other intercom sessions.") + }, + async execute(args, context) { + setActiveSession(context.sessionID); + return resultText(await runtime.setSummary(args.summary)); + } + }), + intercom_send: tool({ + description: "Send a non-blocking message to another local intercom session.", + args: { + to: tool.schema.string().describe("Target session name, id, or unique id prefix."), + message: tool.schema.string().describe("Message text to send.") + }, + async execute(args, context) { + setActiveSession(context.sessionID); + return resultText(await runtime.send(args.to, args.message)); + } + }), + intercom_ask: tool({ + description: "Ask another local intercom session a question only when the next step depends on its reply. Use intercom_send for assignments, progress/status checkpoints, and notifications.", + args: { + to: tool.schema.string().describe("Target session name, id, or unique id prefix."), + message: tool.schema.string().describe("Question text to send."), + timeout_ms: tool.schema.number().optional().describe("Reply timeout in milliseconds, max 120000.") + }, + async execute(args, context) { + setActiveSession(context.sessionID); + const timeoutMs = args.timeout_ms === void 0 ? void 0 : validateAskTimeoutMs(args.timeout_ms); + return resultText(await runtime.ask(args.to, args.message, void 0, timeoutMs)); + } + }), + intercom_pending: tool({ + description: "Read queued inbound intercom messages and unresolved asks.", + args: { + mark_read: tool.schema.boolean().optional().describe("Mark unread messages as read after returning them.") + }, + async execute(args, context) { + setActiveSession(context.sessionID); + return resultText(await runtime.pending(args.mark_read ?? false)); + } + }), + intercom_reply: tool({ + description: "Reply to a pending inbound intercom ask. Use to plus which=oldest/latest when one sender has multiple unresolved asks.", + args: { + message: tool.schema.string().describe("Reply text."), + to: tool.schema.string().optional().describe("Optional sender name/id; never a message or thread ID."), + which: tool.schema.enum(["oldest", "latest"]).optional().describe("Select the oldest or latest ask from the chosen sender.") + }, + async execute(args, context) { + setActiveSession(context.sessionID); + return resultText(await runtime.reply(args.message, args.to, args.which)); + } + }) + }, + event: async ({ event }) => { + const properties = event.properties; + if (event.type === "session.created" || event.type === "session.updated") { + const info = properties?.info; + setActiveSession(info?.id); + } else { + setActiveSession(properties?.sessionID); + } + if (event.type === "session.idle") { + activeSessionStatus = "idle"; + healthReporter.update({ status: "idle", connected: true, error: void 0 }); + await runtime.setSummary("idle"); + await flushPendingInjectQueue("session.idle"); + } else if (event.type === "session.status") { + const status = normalizeOpenCodeSessionStatus(properties?.status); + activeSessionStatus = status; + healthReporter.update({ status, connected: true, error: void 0 }); + await runtime.setSummary(status); + } + } + }; +}; +var plugin_default = OpenCodeIntercomPlugin; + +// opencode/plugin-v2.ts +var toolSchemas = { + agent_fleet: { properties: { action: { type: "string" }, id: { type: "string" }, harness: { type: "string" }, role: { type: "string" }, task: { type: "string" }, cwd: { type: "string" }, profile: { type: "string" }, model: { type: "string" }, effort: { type: "string" }, instructions: { type: "string" }, fresh: { type: "boolean" }, all: { type: "boolean" }, execute: { type: "boolean" }, acknowledge: { type: "boolean" }, lines: { type: "number" } }, required: ["action"] }, + intercom_whoami: { properties: {} }, + intercom_team: { properties: {} }, + intercom_status: { properties: {} }, + intercom_list: { properties: { scope: { type: "string", enum: ["machine", "directory", "repo"] }, include_self: { type: "boolean" } } }, + intercom_set_summary: { properties: { summary: { type: "string" } }, required: ["summary"] }, + intercom_send: { properties: { to: { type: "string" }, message: { type: "string" } }, required: ["to", "message"] }, + intercom_ask: { properties: { to: { type: "string" }, message: { type: "string" }, timeout_ms: { type: "number" } }, required: ["to", "message"] }, + intercom_pending: { properties: { mark_read: { type: "boolean" } } }, + intercom_reply: { properties: { message: { type: "string" }, to: { type: "string" }, which: { type: "string", enum: ["oldest", "latest"] } }, required: ["message"] } +}; +function sameDirectory(left, right) { + return typeof left === "string" && resolve3(left) === resolve3(right); +} +function legacyPart(message, sessionID) { + if (message.type === "user" || message.type === "synthetic" || message.type === "system") { + return { + info: { id: message.id, sessionID, role: "user", agent: message.agent }, + parts: [{ id: `${message.id}-text`, sessionID, messageID: message.id, type: "text", text: message.text ?? "", synthetic: message.type !== "user" }] + }; + } + return { + info: { id: message.id, sessionID, role: "assistant", agent: message.agent }, + parts: (message.content ?? []).map((part, index) => ({ + id: part.id ?? `${message.id}-${index}`, + sessionID, + messageID: message.id, + ...part + })) + }; +} +function legacyClient(ctx) { + return { + app: { + log: async ({ body }) => { + const line = `[${body?.service ?? "agent-intercom"}] ${body?.message ?? ""}`; + body?.level === "warn" ? console.warn(line) : console.info(line); + return { data: true }; + } + }, + tui: { + showToast: async () => ({ data: false }), + appendPrompt: async () => ({ data: false }), + submitPrompt: async () => ({ data: false }) + }, + session: { + list: async () => ({ data: [] }), + get: async ({ path }) => ({ data: await ctx.session.get({ sessionID: path.id }) }), + messages: async ({ path }) => ({ + data: (await ctx.session.context({ sessionID: path.id })).map( + (message) => legacyPart(message, path.id) + ) + }), + promptAsync: async ({ path, body }) => { + const text = (body?.parts ?? []).filter((part) => part?.type === "text").map((part) => part.text ?? "").join("\n"); + const data = await ctx.session.prompt({ + sessionID: path.id, + text, + delivery: "queue", + metadata: body?.parts?.[0]?.metadata + }); + return { data, response: new Response(null, { status: 200 }) }; + } + } + }; +} +function toLegacyEvent(raw) { + const envelope = raw?.payload ?? raw; + const source = envelope?.type === "sync" && envelope.syncEvent ? envelope.syncEvent : envelope; + const type = typeof source?.type === "string" ? source.type.replace(/\.1$/, "") : source?.type; + const data = source?.data ?? {}; + if (source && typeof source === "object" && "properties" in source) return source; + if (type === "session.created" || type === "session.updated") { + return { type, properties: { info: data.session ?? data.info ?? data } }; + } + return { type, properties: data }; +} +async function belongsToLocation(ctx, raw) { + const directory = raw?.directory ?? raw?.payload?.directory ?? raw?.data?.info?.directory; + if (directory) return sameDirectory(directory, ctx.location.directory); + const data = raw?.data ?? raw?.payload?.data ?? raw?.properties; + const sessionID = data?.sessionID ?? data?.session?.id ?? data?.info?.id; + if (!sessionID) return false; + try { + const session = await ctx.session.get({ sessionID }); + return sameDirectory(session?.directory ?? session?.data?.directory, ctx.location.directory); + } catch { + return false; + } +} +function toolResult(value) { + if (typeof value === "string") return { content: value }; + if (value && typeof value === "object" && typeof value.output === "string") { + return { content: value.output, metadata: value.metadata }; + } + return { content: JSON.stringify(value ?? null) }; +} +var OpenCodeIntercomPluginV2 = { + id: "agent-intercom", + async setup(ctx) { + const legacy = await plugin_default({ + client: legacyClient(ctx), + directory: ctx.location.directory, + worktree: ctx.location.project.directory, + project: ctx.location.project, + serverUrl: new URL("http://127.0.0.1") + }, ctx.options); + await ctx.tool.transform((editor) => { + for (const [name, definition] of Object.entries(legacy.tool ?? {})) { + const schema = toolSchemas[name]; + if (!schema) continue; + editor.add({ + name, + description: definition.description, + input: { type: "object", ...schema, additionalProperties: false }, + execute: async (args, toolContext) => toolResult(await definition.execute(args, { + sessionID: toolContext.sessionID, + messageID: toolContext.messageID, + agent: toolContext.agent, + directory: ctx.location.directory, + worktree: ctx.location.project.directory, + abort: new AbortController().signal, + metadata() { + }, + async ask() { + } + })) + }); + } + }); + const announceSession = async (sessionID) => { + await legacy.event?.({ event: { type: "session.updated", properties: { info: { id: sessionID } } } }); + }; + await ctx.session.hook("prompt", (event) => announceSession(event.sessionID)); + await ctx.session.hook("context", (event) => announceSession(event.sessionID)); + const controller = new AbortController(); + const watcher = (async () => { + if (!legacy.event) return; + try { + for await (const raw of ctx.event.subscribe({ signal: controller.signal })) { + if (await belongsToLocation(ctx, raw)) { + await legacy.event({ event: toLegacyEvent(raw) }); + } + } + } catch (error) { + if (!controller.signal.aborted) console.error("agent-intercom event bridge failed", error); + } + })(); + return async () => { + controller.abort(); + await watcher; + await legacy.dispose?.(); + }; + } +}; +var plugin_v2_default = OpenCodeIntercomPluginV2; +export { + plugin_v2_default as default +}; diff --git a/opencode/plugin-contract.test.ts b/opencode/plugin-contract.test.ts index 114b891..234ee17 100644 --- a/opencode/plugin-contract.test.ts +++ b/opencode/plugin-contract.test.ts @@ -7,6 +7,13 @@ test("configured server-plugin bundle exposes only its default factory", async ( assert.equal(typeof plugin.default, "function"); }); +test("OpenCode v2 bundle exposes a native setup plugin", async () => { + const plugin = await import(new URL("../dist/plugin-v2.mjs", import.meta.url).href); + assert.deepEqual(Object.keys(plugin), ["default"]); + assert.equal(plugin.default.id, "agent-intercom"); + assert.equal(typeof plugin.default.setup, "function"); +}); + test("package library bundle retains the public adapter contract", async () => { const library = await import(new URL("../dist/index.mjs", import.meta.url).href); assert.deepEqual(Object.keys(library).sort(), [ diff --git a/opencode/plugin-v2.ts b/opencode/plugin-v2.ts new file mode 100644 index 0000000..d9073fb --- /dev/null +++ b/opencode/plugin-v2.ts @@ -0,0 +1,176 @@ +import type { Context, Plugin } from "@opencode/plugin/promise/plugin"; +import { resolve } from "node:path"; +import OpenCodeIntercomPlugin from "./plugin.ts"; + +type LegacyHookSet = Awaited>; + +const toolSchemas: Record> = { + agent_fleet: { properties: { action: { type: "string" }, id: { type: "string" }, harness: { type: "string" }, role: { type: "string" }, task: { type: "string" }, cwd: { type: "string" }, profile: { type: "string" }, model: { type: "string" }, effort: { type: "string" }, instructions: { type: "string" }, fresh: { type: "boolean" }, all: { type: "boolean" }, execute: { type: "boolean" }, acknowledge: { type: "boolean" }, lines: { type: "number" } }, required: ["action"] }, + intercom_whoami: { properties: {} }, + intercom_team: { properties: {} }, + intercom_status: { properties: {} }, + intercom_list: { properties: { scope: { type: "string", enum: ["machine", "directory", "repo"] }, include_self: { type: "boolean" } } }, + intercom_set_summary: { properties: { summary: { type: "string" } }, required: ["summary"] }, + intercom_send: { properties: { to: { type: "string" }, message: { type: "string" } }, required: ["to", "message"] }, + intercom_ask: { properties: { to: { type: "string" }, message: { type: "string" }, timeout_ms: { type: "number" } }, required: ["to", "message"] }, + intercom_pending: { properties: { mark_read: { type: "boolean" } } }, + intercom_reply: { properties: { message: { type: "string" }, to: { type: "string" }, which: { type: "string", enum: ["oldest", "latest"] } }, required: ["message"] }, +}; + +function sameDirectory(left: unknown, right: string): boolean { + return typeof left === "string" && resolve(left) === resolve(right); +} + +function legacyPart(message: any, sessionID: string): any { + if (message.type === "user" || message.type === "synthetic" || message.type === "system") { + return { + info: { id: message.id, sessionID, role: "user", agent: message.agent }, + parts: [{ id: `${message.id}-text`, sessionID, messageID: message.id, type: "text", text: message.text ?? "", synthetic: message.type !== "user" }], + }; + } + return { + info: { id: message.id, sessionID, role: "assistant", agent: message.agent }, + parts: (message.content ?? []).map((part: any, index: number) => ({ + id: part.id ?? `${message.id}-${index}`, + sessionID, + messageID: message.id, + ...part, + })), + }; +} + +function legacyClient(ctx: Context) { + return { + app: { + log: async ({ body }: any) => { + const line = `[${body?.service ?? "agent-intercom"}] ${body?.message ?? ""}`; + body?.level === "warn" ? console.warn(line) : console.info(line); + return { data: true }; + }, + }, + tui: { + showToast: async () => ({ data: false }), + appendPrompt: async () => ({ data: false }), + submitPrompt: async () => ({ data: false }), + }, + session: { + list: async () => ({ data: [] }), + get: async ({ path }: any) => ({ data: await ctx.session.get({ sessionID: path.id }) }), + messages: async ({ path }: any) => ({ + data: (await ctx.session.context({ sessionID: path.id })).map((message: any) => + legacyPart(message, path.id) + ), + }), + promptAsync: async ({ path, body }: any) => { + const text = (body?.parts ?? []) + .filter((part: any) => part?.type === "text") + .map((part: any) => part.text ?? "") + .join("\n"); + const data = await ctx.session.prompt({ + sessionID: path.id, + text, + delivery: "queue", + metadata: body?.parts?.[0]?.metadata, + }); + return { data, response: new Response(null, { status: 200 }) }; + }, + }, + } as any; +} + +function toLegacyEvent(raw: any) { + const envelope = raw?.payload ?? raw; + const source = envelope?.type === "sync" && envelope.syncEvent ? envelope.syncEvent : envelope; + const type = typeof source?.type === "string" ? source.type.replace(/\.1$/, "") : source?.type; + const data = source?.data ?? {}; + if (source && typeof source === "object" && "properties" in source) return source; + if (type === "session.created" || type === "session.updated") { + return { type, properties: { info: data.session ?? data.info ?? data } }; + } + return { type, properties: data }; +} + +async function belongsToLocation(ctx: Context, raw: any): Promise { + const directory = raw?.directory ?? raw?.payload?.directory ?? raw?.data?.info?.directory; + if (directory) return sameDirectory(directory, ctx.location.directory); + const data = raw?.data ?? raw?.payload?.data ?? raw?.properties; + const sessionID = data?.sessionID ?? data?.session?.id ?? data?.info?.id; + if (!sessionID) return false; + try { + const session: any = await ctx.session.get({ sessionID }); + return sameDirectory(session?.directory ?? session?.data?.directory, ctx.location.directory); + } catch { + return false; + } +} + +function toolResult(value: unknown): { content: string; metadata?: unknown } { + if (typeof value === "string") return { content: value }; + if (value && typeof value === "object" && typeof (value as any).output === "string") { + return { content: (value as any).output, metadata: (value as any).metadata }; + } + return { content: JSON.stringify(value ?? null) }; +} + +const OpenCodeIntercomPluginV2: Plugin = { + id: "agent-intercom", + async setup(ctx) { + const legacy = await OpenCodeIntercomPlugin({ + client: legacyClient(ctx), + directory: ctx.location.directory, + worktree: ctx.location.project.directory, + project: ctx.location.project, + serverUrl: new URL("http://127.0.0.1"), + } as any, ctx.options as any) as LegacyHookSet; + + await ctx.tool.transform((editor) => { + for (const [name, definition] of Object.entries(legacy.tool ?? {})) { + const schema = toolSchemas[name]; + if (!schema) continue; + editor.add({ + name, + description: definition.description, + input: { type: "object", ...schema, additionalProperties: false } as any, + execute: async (args: any, toolContext: any) => toolResult(await definition.execute(args, { + sessionID: toolContext.sessionID, + messageID: toolContext.messageID, + agent: toolContext.agent, + directory: ctx.location.directory, + worktree: ctx.location.project.directory, + abort: new AbortController().signal, + metadata() {}, + async ask() {}, + } as any)) as any, + } as any); + } + }); + + const announceSession = async (sessionID: string) => { + await legacy.event?.({ event: { type: "session.updated", properties: { info: { id: sessionID } } } } as any); + }; + await ctx.session.hook("prompt", (event) => announceSession(event.sessionID)); + await ctx.session.hook("context", (event) => announceSession(event.sessionID)); + + const controller = new AbortController(); + const watcher = (async () => { + if (!legacy.event) return; + try { + for await (const raw of ctx.event.subscribe({ signal: controller.signal })) { + if (await belongsToLocation(ctx, raw)) { + await legacy.event({ event: toLegacyEvent(raw) } as any); + } + } + } catch (error) { + if (!controller.signal.aborted) console.error("agent-intercom event bridge failed", error); + } + })(); + + return async () => { + controller.abort(); + await watcher; + await legacy.dispose?.(); + }; + }, +}; + +export default OpenCodeIntercomPluginV2; diff --git a/package-lock.json b/package-lock.json index c538bfb..1e8ecaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ }, "devDependencies": { "@dataforxyz/agent-intercom-core": "git+https://github.com/dataforxyz/agent-intercom-core.git#8316cbab548f422ad11c78ed887fabeef94817c1", + "@opencode/plugin": "^2.0.3", "@types/node": "^24.0.0", "esbuild": "^0.28.1", "tsx": "^4.20.0", @@ -35,9 +36,482 @@ "node": ">=18" } }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity": { + "version": "3.1057.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1057.0.tgz", + "integrity": "sha512-5MliYkp2u0+2arTp5fZIaxl+xmm90LEKv/VeSxhfNQW4t0fvWJrNO429/jchWQenNoDRrOGE59VfbuZUfwFujg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.15", + "@aws-sdk/credential-provider-node": "^3.972.47", + "@aws-sdk/types": "^3.973.9", + "@smithy/core": "^3.24.5", + "@smithy/fetch-http-handler": "^5.4.5", + "@smithy/node-http-handler": "^4.7.5", + "@smithy/types": "^4.14.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.978.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.978.0.tgz", + "integrity": "sha512-2yX9LUmxPklVjSGTb8dfnWRJSiFQ3TeH2nn7G1mdKHTfnabzF0+gfrS8rYfLWmZrQ8A3mEcxMJjRc51dL5KWaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.974.5", + "@aws-sdk/xml-builder": "^3.972.40", + "@aws/lambda-invoke-store": "^0.3.0", + "@smithy/core": "^3.33.3", + "@smithy/signature-v4": "^5.6.12", + "@smithy/types": "^4.17.2", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-cognito-identity": { + "version": "3.972.70", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.70.tgz", + "integrity": "sha512-KlU89w6Hmb4oZB5zFz/MNIhPOBQGVE7KrDr3BTPCwC4W+q566YH8tGNsAML781LKATtqmNCGFry8XvsJ2XPusg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/nested-clients": "^3.997.45", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.972.71", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.71.tgz", + "integrity": "sha512-JN+JHruYZw3GUZB8YGAlDk4wTDPOEAEEdEzj5nS0xodWR4smzHsN7PnK2j6IeOsDIj2aqua5DSbhXl9Gtf90FQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.978.0", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.972.73", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.73.tgz", + "integrity": "sha512-uyYYnJOnlis8uQzaYGPd7N1JoioCoNpXgnkXYixsWJXHXgXyYi8WXJSDfofxJeWfQIGWLe2Nwyq60Uc7MZdVOg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.978.0", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/fetch-http-handler": "^5.7.2", + "@smithy/node-http-handler": "^4.11.3", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.973.16", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.16.tgz", + "integrity": "sha512-i++ly+0Uxa+u3ebSSyr0S/3CFhFJDxCXT3+Zj+mW2bXenEx5bKGCdTIKFu39SgXBNhWDjex/8cXUx9MUTMCrTw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.978.0", + "@aws-sdk/credential-provider-env": "^3.972.71", + "@aws-sdk/credential-provider-http": "^3.972.73", + "@aws-sdk/credential-provider-login": "^3.972.78", + "@aws-sdk/credential-provider-process": "^3.972.71", + "@aws-sdk/credential-provider-sso": "^3.973.15", + "@aws-sdk/credential-provider-web-identity": "^3.972.77", + "@aws-sdk/nested-clients": "^3.997.45", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/credential-provider-imds": "^4.4.16", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.78", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.78.tgz", + "integrity": "sha512-eUtswnXu0+Ii9ieRK+0L7aPFV3Z/dnW2VntJzjBP9xs8s+8p5nBNuymIXtXwZ+5r5+XJP3e32nMkuZ/r0HozEA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.978.0", + "@aws-sdk/nested-clients": "^3.997.45", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.972.83", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.83.tgz", + "integrity": "sha512-jdso7ejzfRnatxMUZK4S/U6KbaDPCvfIV4XL+IQAPFDBt5rj5Fq595euqlK8Le4lNCMFR9oUpt+1l0aMgaayOQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "^3.972.71", + "@aws-sdk/credential-provider-http": "^3.972.73", + "@aws-sdk/credential-provider-ini": "^3.973.16", + "@aws-sdk/credential-provider-process": "^3.972.71", + "@aws-sdk/credential-provider-sso": "^3.973.15", + "@aws-sdk/credential-provider-web-identity": "^3.972.77", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/credential-provider-imds": "^4.4.16", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.972.71", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.71.tgz", + "integrity": "sha512-lYmXJa4gvq4xN1lrT5NiP5vIYYKcGWAdj8y+8o6dlcateB5eF3Dn8DtmjjHKfMBrTPAMr2pebIiX/UOj8c1/UA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.978.0", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.973.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.15.tgz", + "integrity": "sha512-6Jhcf4v0pSFdjk1EW2kvzuEBKD+UZ2uNcHUIglKKLndD20YhvkL2kdmDOV5/j4mYuWWwe/a1FQ1aomU86/Cg5Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.978.0", + "@aws-sdk/nested-clients": "^3.997.45", + "@aws-sdk/token-providers": "3.1129.0", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.972.77", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.77.tgz", + "integrity": "sha512-uylIQSUWpfLuH2LovxEEfwzJGM/SabLOfLMg6YXu/E8jJEKUdpdILCVCQCdFvHyu/7dLJOHPMfrSwduxO56NkQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.978.0", + "@aws-sdk/nested-clients": "^3.997.45", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-providers": { + "version": "3.1057.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.1057.0.tgz", + "integrity": "sha512-rbrEHtz11g0kxsSkYr3fx2HABNNblp4AhB2MgPvJHgYOWfJ2eBviU7Mvoaef0PW8QH6lbZDfJcnM7eKvtvz3sw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.1057.0", + "@aws-sdk/core": "^3.974.15", + "@aws-sdk/credential-provider-cognito-identity": "^3.972.38", + "@aws-sdk/credential-provider-env": "^3.972.41", + "@aws-sdk/credential-provider-http": "^3.972.43", + "@aws-sdk/credential-provider-ini": "^3.972.46", + "@aws-sdk/credential-provider-login": "^3.972.45", + "@aws-sdk/credential-provider-node": "^3.972.47", + "@aws-sdk/credential-provider-process": "^3.972.41", + "@aws-sdk/credential-provider-sso": "^3.972.45", + "@aws-sdk/credential-provider-web-identity": "^3.972.45", + "@aws-sdk/nested-clients": "^3.997.13", + "@aws-sdk/types": "^3.973.9", + "@smithy/core": "^3.24.5", + "@smithy/credential-provider-imds": "^4.3.6", + "@smithy/types": "^4.14.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.997.45", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.45.tgz", + "integrity": "sha512-mooq9Q+jLa18VoM7HouczmslZU60iiB0aKc/Ztnq/luIL1ud0z4DnYprLR/ZO1gp331S9tJctM1HZr7u6YKBXQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.978.0", + "@aws-sdk/signature-v4-multi-region": "^3.996.46", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/fetch-http-handler": "^5.7.2", + "@smithy/node-http-handler": "^4.11.3", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.996.46", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.46.tgz", + "integrity": "sha512-L+2xZTye/2T96f3lwCws0Zw6GG2JHZW9e8FpVgGBeeExSKyeoZ6CWRpBml/7DNiK/O26jrgPM9F+Ay8VkgzUWQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.974.5", + "@smithy/signature-v4": "^5.6.12", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.1129.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1129.0.tgz", + "integrity": "sha512-Sbl3rpzQdsG4ZK2zh0JWUYyZPKKorJlVOddA2T0DVbKJFrsW8J6wgnslxxUH04+WaBMr4A1HzJZvZX0xUvkniA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.978.0", + "@aws-sdk/nested-clients": "^3.997.45", + "@aws-sdk/types": "^3.974.5", + "@smithy/core": "^3.33.3", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.974.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.974.5.tgz", + "integrity": "sha512-LkwLL2BLbC6wNNm4JaH9mbEqBMdOZCct6VAYqhdN4U1xrWM+fUJQEfbHwQgDypapOWTRtlk25akb5afM0P8CIQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.10.tgz", + "integrity": "sha512-ycwH6Zd2GhuSqdXX9ihbCjeGTB6xOJs+O3+Jb8/zDG9978XU80qs75dfkPJRMNKe5MvBZPuNeFpd4JZKPoUF4g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.972.40", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.40.tgz", + "integrity": "sha512-wlFmCIGUlwF4zx/kncw+bmxTQh1HeSJq4mYV/V5cZUSJadDP3kXvGW8Rn21cimj/7y9ju+47oYWXi97vF7czaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.3.0.tgz", + "integrity": "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@dataforxyz/agent-intercom-core": { "version": "0.1.0", - "resolved": "git+https://github.com/dataforxyz/agent-intercom-core.git#8316cbab548f422ad11c78ed887fabeef94817c1", + "resolved": "git+ssh://git@github.com/dataforxyz/agent-intercom-core.git#8316cbab548f422ad11c78ed887fabeef94817c1", "integrity": "sha512-tGEdYHG/Zrl/VSkOQMpjZ8LgnxG4O7youbVOEjZVwG+XbjhLVkDOeODa+U3plIUwbCVIXJHodmbJuH0yW5SIRA==", "dev": true, "license": "AGPL-3.0-or-later", @@ -488,6 +962,54 @@ "node": ">=18" } }, + "node_modules/@gar/promise-retry": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@gar/promise-retry/-/promise-retry-1.0.3.tgz", + "integrity": "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", + "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", + "dev": true, + "license": "ISC" + }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz", @@ -564,129 +1086,2871 @@ "win32" ] }, - "node_modules/@opencode-ai/plugin": { - "version": "1.17.15", - "license": "MIT", + "node_modules/@npmcli/agent": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.2.tgz", + "integrity": "sha512-EUEuWAxnL07Sp5/iC/1X6Xj+XThUvnbei9zfRWZdEXa7lss9RTHMhAHBeg+MZ5To9s/gGaSI+UwZTPdYMvKSeg==", + "dev": true, + "license": "ISC", "dependencies": { - "@ai-sdk/provider": "3.0.8", - "@opencode-ai/sdk": "1.17.15", - "effect": "4.0.0-beta.83", - "zod": "4.1.8" - }, - "peerDependencies": { - "@opentui/core": ">=0.4.3", - "@opentui/keymap": ">=0.4.3", - "@opentui/solid": ">=0.4.3" + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^8.0.3" }, - "peerDependenciesMeta": { - "@opentui/core": { - "optional": true - }, - "@opentui/keymap": { - "optional": true - }, - "@opentui/solid": { - "optional": true - } + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@opencode-ai/sdk": { - "version": "1.17.15", - "license": "MIT", + "node_modules/@npmcli/arborist": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-9.4.0.tgz", + "integrity": "sha512-4Bm8hNixJG/sii1PMnag0V9i/sGOX9VRzFrUiZMSBJpGlLR38f+Btl85d07G9GL56xO0l0OZjvrGNYsDYp0xKA==", + "dev": true, + "license": "ISC", "dependencies": { - "cross-spawn": "7.0.6" + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^5.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/metavuln-calculator": "^9.0.2", + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/query": "^5.0.0", + "@npmcli/redact": "^4.0.0", + "@npmcli/run-script": "^10.0.0", + "bin-links": "^6.0.0", + "cacache": "^20.0.1", + "common-ancestor-path": "^2.0.0", + "hosted-git-info": "^9.0.0", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^11.2.1", + "minimatch": "^10.0.3", + "nopt": "^9.0.0", + "npm-install-checks": "^8.0.0", + "npm-package-arg": "^13.0.0", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "pacote": "^21.0.2", + "parse-conflict-json": "^5.0.1", + "proc-log": "^6.0.0", + "proggy": "^4.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "semver": "^7.3.7", + "ssri": "^13.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^4.0.0" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.13.3", + "node_modules/@npmcli/config": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-10.8.1.tgz", + "integrity": "sha512-MAYk9IlIGiyC0c9fnjdBSQfIFPZT0g1MfeSiD1UXTq2zJOLX55jS9/sETJHqw/7LN18JjITrhYfgCfapbmZHiQ==", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "ci-info": "^4.0.0", + "ini": "^6.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "walk-up-path": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/config/node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/fs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", + "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/git": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.2.tgz", + "integrity": "sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/git/node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", + "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/map-workspaces": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-5.0.3.tgz", + "integrity": "sha512-o2grssXo1e774E5OtEwwrgoszYRh0lqkJH+Pb9r78UcqdGJRDRfhpM8DvZPjzNLLNYeD/rNbjOKM3Ss5UABROw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "glob": "^13.0.0", + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/metavuln-calculator": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-9.0.3.tgz", + "integrity": "sha512-94GLSYhLXF2t2LAC7pDwLaM4uCARzxShyAQKsirmlNcpidH89VA4/+K1LbJmRMgz5gy65E/QBBWQdUvGLe2Frg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cacache": "^20.0.0", + "json-parse-even-better-errors": "^5.0.0", + "pacote": "^21.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/name-from-folder": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-4.0.0.tgz", + "integrity": "sha512-qfrhVlOSqmKM8i6rkNdZzABj8MKEITGFAY+4teqBziksCQAOLutiAxM1wY2BKEd8KjUSpWmWCYxvXr0y4VTlPg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", + "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.5.tgz", + "integrity": "sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "spdx-expression-parse": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", + "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/query/-/query-5.0.0.tgz", + "integrity": "sha512-8TZWfTQOsODpLqo9SVhVjHovmKXNpevHU0gO9e+y4V4fRIOneiXy0u0sMP9LmS71XivrEWfZWg50ReH4WRT4aQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", + "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.4.tgz", + "integrity": "sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@opencode-ai/plugin": { + "version": "1.17.15", + "license": "MIT", + "dependencies": { + "@ai-sdk/provider": "3.0.8", + "@opencode-ai/sdk": "1.17.15", + "effect": "4.0.0-beta.83", + "zod": "4.1.8" + }, + "peerDependencies": { + "@opentui/core": ">=0.4.3", + "@opentui/keymap": ">=0.4.3", + "@opentui/solid": ">=0.4.3" + }, + "peerDependenciesMeta": { + "@opentui/core": { + "optional": true + }, + "@opentui/keymap": { + "optional": true + }, + "@opentui/solid": { + "optional": true + } + } + }, + "node_modules/@opencode-ai/sdk": { + "version": "1.17.15", + "license": "MIT", + "dependencies": { + "cross-spawn": "7.0.6" + } + }, + "node_modules/@opencode/ai": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@opencode/ai/-/ai-2.0.3.tgz", + "integrity": "sha512-SqrFdmgwCDWug95v7vpkT8asd64i/iimK67BVzvuCbtLfzWdUljzp3No4ytHXyVqLt/XkdyOuJA/NoGrDM8muw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@aws-sdk/credential-providers": "3.1057.0", + "@opencode/schema": "2.0.3", + "@smithy/eventstream-codec": "4.2.14", + "@smithy/util-utf8": "4.2.2", + "aws4fetch": "1.0.20", + "effect": "4.0.0-rc.112", + "google-auth-library": "10.5.0" + } + }, + "node_modules/@opencode/ai/node_modules/effect": { + "version": "4.0.0-rc.112", + "resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-rc.112.tgz", + "integrity": "sha512-wXxwuh1Ywnv4cPRM3Wfa0vDwuOHnZ1TsTgHJkG9XgzND6inhBH9n1vBxhg3iIXOia/OrpmvVmd3lrD4vq6bF3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-check": "^4.9.0", + "msgpackr": "^2.0.5" + } + }, + "node_modules/@opencode/plugin": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@opencode/plugin/-/plugin-2.0.3.tgz", + "integrity": "sha512-4xLLwi9PnUXHtfvsxVe7oVhRl/q8VRIFQS4Lfh3yjClfymIfyfX5/jCSwSbgTf5NgdrNGr20OPcjONZvCTPznA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ai-sdk/provider": "3.0.8", + "@opencode/ai": "2.0.3", + "@opencode/client": "2.0.3", + "@opencode/protocol": "2.0.3", + "@opencode/schema": "2.0.3", + "@opencode/util": "2.0.3", + "@standard-schema/spec": "1.1.0", + "effect": "4.0.0-rc.112", + "zod": "4.1.8" + }, + "peerDependencies": { + "@opencode/theme": "2.0.3", + "@opentui/core": ">=0.5.10", + "@opentui/solid": ">=0.5.10", + "solid-js": ">=1.9.0" + }, + "peerDependenciesMeta": { + "@opencode/theme": { + "optional": true + }, + "@opentui/core": { + "optional": true + }, + "@opentui/solid": { + "optional": true + }, + "solid-js": { + "optional": true + } + } + }, + "node_modules/@opencode/plugin/node_modules/@opencode/client": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@opencode/client/-/client-2.0.3.tgz", + "integrity": "sha512-b+LcpMI131fXnGqf+O+9Y33H4XmwAkQibfYvtpEOROftkTpkcMj3R7WW/wGl2VTBNTZECAk2Yd+TACTzzAwk0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@opencode/protocol": "2.0.3", + "@opencode/schema": "2.0.3" + }, + "peerDependencies": { + "effect": "4.0.0-rc.112", + "solid-js": ">=1.9.0" + }, + "peerDependenciesMeta": { + "effect": { + "optional": true + }, + "solid-js": { + "optional": true + } + } + }, + "node_modules/@opencode/plugin/node_modules/effect": { + "version": "4.0.0-rc.112", + "resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-rc.112.tgz", + "integrity": "sha512-wXxwuh1Ywnv4cPRM3Wfa0vDwuOHnZ1TsTgHJkG9XgzND6inhBH9n1vBxhg3iIXOia/OrpmvVmd3lrD4vq6bF3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-check": "^4.9.0", + "msgpackr": "^2.0.5" + } + }, + "node_modules/@opencode/protocol": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@opencode/protocol/-/protocol-2.0.3.tgz", + "integrity": "sha512-DNHbkLDTuAyMsmVdnjuKulcfoDbllW2dxt4W19r2aJEYvswJpEO9168CSK6Sjbx1FOh/B9yL7SQgoDRMd4K5Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@opencode/schema": "2.0.3", + "effect": "4.0.0-rc.112" + } + }, + "node_modules/@opencode/protocol/node_modules/effect": { + "version": "4.0.0-rc.112", + "resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-rc.112.tgz", + "integrity": "sha512-wXxwuh1Ywnv4cPRM3Wfa0vDwuOHnZ1TsTgHJkG9XgzND6inhBH9n1vBxhg3iIXOia/OrpmvVmd3lrD4vq6bF3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-check": "^4.9.0", + "msgpackr": "^2.0.5" + } + }, + "node_modules/@opencode/schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@opencode/schema/-/schema-2.0.3.tgz", + "integrity": "sha512-thPeBbqw4+SkZ/0LOuqfahSRGuWogRa/wwfIVyiQYsoE0vzLx8XUpHQ+FSUWkdz6llDtP0+ZsyBqXUMpXmPgbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "1.1.0", + "effect": "4.0.0-rc.112" + } + }, + "node_modules/@opencode/schema/node_modules/effect": { + "version": "4.0.0-rc.112", + "resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-rc.112.tgz", + "integrity": "sha512-wXxwuh1Ywnv4cPRM3Wfa0vDwuOHnZ1TsTgHJkG9XgzND6inhBH9n1vBxhg3iIXOia/OrpmvVmd3lrD4vq6bF3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-check": "^4.9.0", + "msgpackr": "^2.0.5" + } + }, + "node_modules/@opencode/util": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@opencode/util/-/util-2.0.3.tgz", + "integrity": "sha512-6DQyOUtJW0kU6pLBEpncIyUH1nmXa8Z2jcsBEYummKmHCwZaiIkBowjWMGWKsV4G42IPMP1jYUMfD9hTRmX+RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@effect/opentelemetry": "4.0.0-rc.112", + "@effect/platform-node": "4.0.0-rc.112", + "@effect/platform-node-shared": "4.0.0-rc.112", + "@npmcli/arborist": "9.4.0", + "@npmcli/config": "10.8.1", + "@opentelemetry/api": "1.9.0", + "@opentelemetry/context-async-hooks": "2.6.1", + "@opentelemetry/exporter-trace-otlp-http": "0.214.0", + "@opentelemetry/sdk-trace-base": "2.6.1", + "@opentelemetry/sdk-trace-node": "2.6.1", + "cross-spawn": "7.0.6", + "effect": "4.0.0-rc.112", + "glob": "13.0.5", + "mime-types": "3.0.2", + "minimatch": "10.2.5", + "npm-package-arg": "13.0.2", + "pacote": "21.5.1" + } + }, + "node_modules/@opencode/util/node_modules/@effect/opentelemetry": { + "version": "4.0.0-rc.112", + "resolved": "https://registry.npmjs.org/@effect/opentelemetry/-/opentelemetry-4.0.0-rc.112.tgz", + "integrity": "sha512-OTRv1DxTHUmnakgJ6XVM8wVgF1KgZH4UXnOemwSLUwUjXO+RCikzF8oR/rlVmOGq81KtQzj1URM4M4nchlQOuQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <2.0.0", + "@opentelemetry/api-logs": ">=0.203.0 <0.300.0", + "@opentelemetry/resources": ">=2.0.0 <3.0.0", + "@opentelemetry/sdk-logs": ">=0.203.0 <0.300.0", + "@opentelemetry/sdk-metrics": ">=2.0.0 <3.0.0", + "@opentelemetry/sdk-trace-base": ">=2.0.0 <3.0.0", + "@opentelemetry/sdk-trace-node": ">=2.0.0 <3.0.0", + "@opentelemetry/sdk-trace-web": ">=2.0.0 <3.0.0", + "@opentelemetry/semantic-conventions": ">=1.33.0 <2.0.0", + "effect": "^4.0.0-rc.112" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/api-logs": { + "optional": true + }, + "@opentelemetry/resources": { + "optional": true + }, + "@opentelemetry/sdk-logs": { + "optional": true + }, + "@opentelemetry/sdk-metrics": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { + "optional": true + }, + "@opentelemetry/sdk-trace-node": { + "optional": true + }, + "@opentelemetry/sdk-trace-web": { + "optional": true + } + } + }, + "node_modules/@opencode/util/node_modules/@effect/platform-node": { + "version": "4.0.0-rc.112", + "resolved": "https://registry.npmjs.org/@effect/platform-node/-/platform-node-4.0.0-rc.112.tgz", + "integrity": "sha512-/BMAcdNGQQskLmI0Zoa95KfTZkr9HV9N4NSxaSrusG6GeW6Ulp9KvZ+Rlaiw8lnOt43CXjFLdfll5/k5rxL4hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@effect/platform-node-shared": "^4.0.0-rc.112", + "mime": "^4.1.0", + "undici": "^8.10.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "effect": "^4.0.0-rc.112", + "redis": ">=5.0.0 <7.0.0" + } + }, + "node_modules/@opencode/util/node_modules/@effect/platform-node-shared": { + "version": "4.0.0-rc.112", + "resolved": "https://registry.npmjs.org/@effect/platform-node-shared/-/platform-node-shared-4.0.0-rc.112.tgz", + "integrity": "sha512-ttjz0xKamFN7vL8pNDYVwddJLjZvqKePc05djlz2VcdaKbLsnYbtMnL1rbOfHgEnIUSHGh7FkjaN4DM1Ov81sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ws": "^8.18.1", + "ws": "^8.21.3" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "effect": "^4.0.0-rc.112" + } + }, + "node_modules/@opencode/util/node_modules/effect": { + "version": "4.0.0-rc.112", + "resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-rc.112.tgz", + "integrity": "sha512-wXxwuh1Ywnv4cPRM3Wfa0vDwuOHnZ1TsTgHJkG9XgzND6inhBH9n1vBxhg3iIXOia/OrpmvVmd3lrD4vq6bF3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-check": "^4.9.0", + "msgpackr": "^2.0.5" + } + }, + "node_modules/@opencode/util/node_modules/undici": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.10.2.tgz", + "integrity": "sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.214.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.214.0.tgz", + "integrity": "sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.6.1.tgz", + "integrity": "sha512-XHzhwRNkBpeP8Fs/qjGrAf9r9PRv67wkJQ/7ZPaBQQ68DYlTBBx5MF9LvPx7mhuXcDessKK2b+DcxqwpgkcivQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.6.1.tgz", + "integrity": "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.214.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.214.0.tgz", + "integrity": "sha512-kIN8nTBMgV2hXzV/a20BCFilPZdAIMYYJGSgfMMRm/Xa+07y5hRDS2Vm12A/z8Cdu3Sq++ZvJfElokX2rkgGgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.6.1", + "@opentelemetry/otlp-exporter-base": "0.214.0", + "@opentelemetry/otlp-transformer": "0.214.0", + "@opentelemetry/resources": "2.6.1", + "@opentelemetry/sdk-trace-base": "2.6.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.214.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.214.0.tgz", + "integrity": "sha512-u1Gdv0/E9wP+apqWf7Wv2npXmgJtxsW2XL0TEv9FZloTZRuMBKmu8cYVXwS4Hm3q/f/3FuCnPTgiwYvIqRSpRg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.6.1", + "@opentelemetry/otlp-transformer": "0.214.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.214.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.214.0.tgz", + "integrity": "sha512-DSaYcuBRh6uozfsWN3R8HsN0yDhCuWP7tOFdkUOVaWD1KVJg8m4qiLUsg/tNhTLS9HUYUcwNpwL2eroLtsZZ/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.214.0", + "@opentelemetry/core": "2.6.1", + "@opentelemetry/resources": "2.6.1", + "@opentelemetry/sdk-logs": "0.214.0", + "@opentelemetry/sdk-metrics": "2.6.1", + "@opentelemetry/sdk-trace-base": "2.6.1", + "protobufjs": "^7.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.6.1.tgz", + "integrity": "sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.6.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.214.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.214.0.tgz", + "integrity": "sha512-zf6acnScjhsaBUU22zXZ/sLWim1dfhUAbGXdMmHmNG3LfBnQ3DKsOCITb2IZwoUsNNMTogqFKBnlIPPftUgGwA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.214.0", + "@opentelemetry/core": "2.6.1", + "@opentelemetry/resources": "2.6.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.6.1.tgz", + "integrity": "sha512-9t9hJHX15meBy2NmTJxL+NJfXmnausR2xUDvE19XQce0Qi/GBtDGamU8nS1RMbdgDmhgpm3VaOu2+fiS/SfTpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.6.1", + "@opentelemetry/resources": "2.6.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.6.1.tgz", + "integrity": "sha512-r86ut4T1e8vNwB35CqCcKd45yzqH6/6Wzvpk2/cZB8PsPLlZFTvrh8yfOS3CYZYcUmAx4hHTZJ8AO8Dj8nrdhw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.6.1", + "@opentelemetry/resources": "2.6.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.6.1.tgz", + "integrity": "sha512-Hh2i4FwHWRFhnO2Q/p6svMxy8MPsNCG0uuzUY3glqm0rwM0nQvbTO1dXSp9OqQoTKXcQzaz9q1f65fsurmOhNw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "2.6.1", + "@opentelemetry/core": "2.6.1", + "@opentelemetry/sdk-trace-base": "2.6.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz", + "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@redis/bloom": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-6.2.1.tgz", + "integrity": "sha512-huQgNLaCIZfQ9SeLn4q9124uOUd8HbZDYHwwUzNcRgHqCHiHKl2dDxMqJCeWh8cMqZAoWuHR8XnWbDMIf+o7ag==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 20.0.0" + }, + "peerDependencies": { + "@redis/client": "^6.2.1" + } + }, + "node_modules/@redis/client": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-6.2.1.tgz", + "integrity": "sha512-LzxBY7SIBvvJiyCgcaJZZakE3fJrZZ++i24+EDW9fKpCl68D35uJcKFpZZwCfOoG9WZTbyZlMzMeM0gtOAMU9Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "cluster-key-slot": "1.1.2" + }, + "engines": { + "node": ">= 20.0.0" + }, + "peerDependencies": { + "@node-rs/xxhash": "^1.1.0", + "@opentelemetry/api": ">=1 <2" + }, + "peerDependenciesMeta": { + "@node-rs/xxhash": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + } + } + }, + "node_modules/@redis/json": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-6.2.1.tgz", + "integrity": "sha512-AFIUJ8Gj0DaaSBHYuSt8+O0oYWM+50OK1c0OmodB7XERIA8+BbyV3O4v76f9iccWasd1/7qjfZTpuzexUaZtrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 20.0.0" + }, + "peerDependencies": { + "@redis/client": "^6.2.1" + } + }, + "node_modules/@redis/search": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-6.2.1.tgz", + "integrity": "sha512-2vfOAOyYFE7UUw3sBBlkqqruBtOUS4HRY5MtW4hp83llrwvtrTE4r22CEqXddlV+54zkLxBE4nmsIJ/dpezQrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 20.0.0" + }, + "peerDependencies": { + "@redis/client": "^6.2.1" + } + }, + "node_modules/@redis/time-series": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-6.2.1.tgz", + "integrity": "sha512-kiYniph04dJOole+L359B6C9E+jYS2uDP7hca6Onj0xF38ZIpyxARO0Iq0W4ZRn1e8Q6vqW00QFZVSMRA/2Ijw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 20.0.0" + }, + "peerDependencies": { + "@redis/client": "^6.2.1" + } + }, + "node_modules/@sigstore/bundle": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", + "integrity": "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/core": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.2.1.tgz", + "integrity": "sha512-qRsxPnCrbC/puegGxKuynfnxgLiHqWStrSjxkoB4YKqq3Z3s4cyZyj42ZdWFAEblNP65C+rBH8EuREHIXoi83g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.2.tgz", + "integrity": "sha512-SQqvFMt4V78fdjcDdYX6HbiVSOR4QK3ZgwCa2KOsopAgPIHy1rU5UDUmzLl02r5oyyaYcYHR1hpwDRk/yUe+Mw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.1.tgz", + "integrity": "sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@gar/promise-retry": "^1.0.2", + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.4", + "proc-log": "^6.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.2.tgz", + "integrity": "sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.1.tgz", + "integrity": "sha512-qv7+G3J2cc6wwFj3yKvXOamzqhMwSk1ogPGmhpS8iXllcPrJaIIBA+4HbttlHVu1pqWTdmaCH/WE7UOC51kdoA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.1", + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.34.1", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.34.1.tgz", + "integrity": "sha512-dLcOUxz8YCv1RZUMKq6GbyUf95pLbrqh34bPvpCZ1+CByFF31BEAFewZjsGCnVsZTKdThNENfGyAgk2TJqVwSw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.18.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.5.2.tgz", + "integrity": "sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.33.2", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.14.tgz", + "integrity": "sha512-erZq0nOIpzfeZdCyzZjdJb4nVSKLUmSkaQUVkRGQTXs30gyUGeKnrYEg+Xe1W5gE3aReS7IgsvANwVPxSzY6Pw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.14.1", + "@smithy/util-hex-encoding": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.8.0.tgz", + "integrity": "sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.33.3", + "@smithy/types": "^4.18.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.12.1.tgz", + "integrity": "sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.33.3", + "@smithy/types": "^4.18.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.7.3.tgz", + "integrity": "sha512-7ImGm+FkHRLcBaRttIAMZ6bzJZWb2cJGoYjq46F2UjycujWzrL9GEN9h4w7eQyXJYnltrUhxbbieBAIRrdqpow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.33.3", + "@smithy/types": "^4.17.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.18.0.tgz", + "integrity": "sha512-CgB6HHWer/vrKps24ulRIbpcpb7K4xAU7SkZ7YHzBPlwHsvsrCJFEXK421s+cJzX+ZrqtA/TuU5w1HzI7k9N8A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.5.2.tgz", + "integrity": "sha512-nxu3SgmAw9JXT2CtkU0m/XNLWpP9MsaBx1zAGAypCbYj15tIFlmcYwpF+Oh18le83d+IM9PT7ENdXnE4C+d5mA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.33.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.5.2.tgz", + "integrity": "sha512-iq+cW3mAb7vfcxEEpYi3zXKpDtbrIFyanWjQl4zBq4seWD4OSxXDWSfespZxenX6aEaighn+NR3u1nU1DSvs3w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.33.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.1.0.tgz", + "integrity": "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^10.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@types/node": { + "version": "24.13.3", + "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~7.18.0" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aws4fetch": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/aws4fetch/-/aws4fetch-1.0.20.tgz", + "integrity": "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bin-links": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-6.0.2.tgz", + "integrity": "sha512-frE1t78WOwJ45PKV2cF2tNPjTcs9L1J9s6VkrV59wanRP4GlaomuxYPVma7BwthMg8WnfSory4w5PTE6FZZ81w==", + "dev": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "proc-log": "^6.0.0", + "read-cmd-shim": "^6.0.0", + "write-file-atomic": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/cacache": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.4.tgz", + "integrity": "sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^5.0.0", + "fs-minipass": "^3.0.0", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cmd-shim": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-8.0.0.tgz", + "integrity": "sha512-Jk/BK6NCapZ58BKUxlSI+ouKRbjH1NLZCgJkYoab+vEHUY3f6OzpNBN9u7HFSv9J6TRDGs4PLOHezoKGaFRSCA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/common-ancestor-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-2.0.0.tgz", + "integrity": "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">= 18" + } + }, + "node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/effect": { + "version": "4.0.0-beta.83", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "fast-check": "^4.8.0", + "find-my-way-ts": "^0.1.6", + "ini": "^7.0.0", + "kubernetes-types": "^1.30.0", + "msgpackr": "^2.0.1", + "multipasta": "^0.2.7", + "toml": "^4.1.1", + "uuid": "^14.0.0", + "yaml": "^2.9.0" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/esbuild": { + "version": "0.28.1", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-check": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.10.1.tgz", + "integrity": "sha512-sB5Vghiu8MyCyToHoBVGsT0baZg3sZWNIY+a6Ct2EDrQJlT4YdH6MC1BSLNe3kX1k5i5g0q1O52XFgcKK/rGHg==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^8.0.0" + }, + "engines": { + "node": ">=12.17.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/find-my-way-ts": { + "version": "0.1.6", + "license": "MIT" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gaxios": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.3.1.tgz", + "integrity": "sha512-kB3rzJV7d9juLZh8/56QTXCwQfxyhdOMdyYk1HdQKFtF8TJTDTZQJtixWIwXdE9Jji91mC41DUNpjleo4L4eAQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/gcp-metadata": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.4.tgz", + "integrity": "sha512-iJ9KMsiu+xKtNRX0PmGLSaIU3bUBAyzWTyqKemKPzNPsmmsBCQYmlNg+brEbES7IHSXtdVwzBPzx1vz3FAaipw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "gaxios": "7.1.3", + "google-logging-utils": "1.1.3", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/gcp-metadata/node_modules/gaxios": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/gcp-metadata/node_modules/google-logging-utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/glob": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.5.tgz", + "integrity": "sha512-BzXxZg24Ibra1pbQ/zE7Kys4Ua1ks7Bn6pKLkVPZ9FZe4JQS6/Q7ef3LG1H+k7lUf5l4T3PLSyYyYJVYUvfgTw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/google-auth-library": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", + "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^7.0.0", + "gcp-metadata": "^8.0.0", + "google-logging-utils": "^1.0.0", + "gtoken": "^8.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/google-logging-utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.2.0.tgz", + "integrity": "sha512-WE9av4wKDZgRjBwgVUabocx8T6/7o3Ca1Fat46FXDhXVAFibzNadedcOXrdgd1Kzmk8tsk/9ZH89Wyf/SqeZ3A==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/gtoken": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", + "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "gaxios": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/hosted-git-info": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", + "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore-walk": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", + "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/ini": { + "version": "7.0.0", + "license": "ISC", + "engines": { + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" + } + }, + "node_modules/ip-address": { + "version": "10.7.2", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.2.tgz", + "integrity": "sha512-7H/2gFSIitxc0hG3nOI1glS8QLo/EHBFFLk8vEUjXY/xu0AdL8jZ9U1IzO2PUm0d2D/ofQcAifb0g6OBkt8U7w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", + "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/json-schema": { + "version": "0.4.0", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-stringify-nice": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz", + "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/just-diff": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-6.0.2.tgz", + "integrity": "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==", + "dev": true, + "license": "MIT" + }, + "node_modules/just-diff-apply": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.5.0.tgz", + "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kubernetes-types": { + "version": "1.30.0", + "license": "Apache-2.0" + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/make-fetch-happen": { + "version": "15.0.6", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.6.tgz", + "integrity": "sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/agent": "^4.0.0", + "@npmcli/redact": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/mime": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.1.0.tgz", + "integrity": "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa" + ], + "license": "MIT", + "bin": { + "mime": "bin/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.2.tgz", + "integrity": "sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^2.0.0", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "optionalDependencies": { + "iconv-lite": "^0.7.2" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", + "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-2.0.0.tgz", + "integrity": "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-2.1.0.tgz", + "integrity": "sha512-p/pBCVO63CsvvpkomUnNNag6+n38rULuDA6HHe70o2gtC8ODI52foF/4ko2qQcp6OiErJXTmrZeXmsGGHsIQNQ==", + "license": "MIT", + "optionalDependencies": { + "msgpackr-extract": "^3.0.4" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.4", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" + } + }, + "node_modules/multipasta": { + "version": "0.2.8", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz", + "integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "content-type": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-gyp": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.4.0.tgz", + "integrity": "sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "undici": "^6.25.0", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-bundled": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", + "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-install-checks": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", + "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", + "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-package-arg": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.2.tgz", + "integrity": "sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-packlist": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.4.tgz", + "integrity": "sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", + "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz", + "integrity": "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^4.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^15.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/p-map": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.8.tgz", + "integrity": "sha512-MitaVsCuCFIvOLLPIU7NnfrZvS9H9h7kwMUkDo+T2pEISaJD48IV9S8iIdXB7PsvvdxyYcsSTTrr90XKsbulNw==", + "dev": true, "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pacote": { + "version": "21.5.1", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.5.1.tgz", + "integrity": "sha512-KvcJ9iy3crysCsgqc4+PknH/w6jkrp8JN36mpZBPwNaDRwTfMZD37YzRazNstiZUOhuF5pno9f78n9mEJBavwg==", + "dev": true, + "license": "ISC", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "@gar/promise-retry": "^1.0.0", + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" + }, + "bin": { + "pacote": "bin/index.js" }, "engines": { - "node": ">= 8" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "license": "Apache-2.0", - "optional": true, + "node_modules/parse-conflict-json": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-5.0.1.tgz", + "integrity": "sha512-ZHEmNKMq1wyJXNwLxyHnluPfRAFSIliBvbK/UiOceROt4Xh9Pz0fq49NytIaeaCUf5VR86hwQ/34FCcNU5/LKQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^5.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, "engines": { - "node": ">=8" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/effect": { - "version": "4.0.0-beta.83", + "node_modules/path-key": { + "version": "3.1.1", "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "@standard-schema/spec": "^1.1.0", - "fast-check": "^4.8.0", - "find-my-way-ts": "^0.1.6", - "ini": "^7.0.0", - "kubernetes-types": "^1.30.0", - "msgpackr": "^2.0.1", - "multipasta": "^0.2.7", - "toml": "^4.1.1", - "uuid": "^14.0.0", - "yaml": "^2.9.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/esbuild": { - "version": "0.28.1", + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz", + "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=18" + "node": ">=4" + } + }, + "node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/proggy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/proggy/-/proggy-4.0.0.tgz", + "integrity": "sha512-MbA4R+WQT76ZBm/5JUpV9yqcJt92175+Y0Bodg3HgiXzrmKu7Ggq+bpn6y6wHH+gN9NcyKn3yg1+d47VaKwNAQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/promise-all-reject-late": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/promise-call-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-3.0.2.tgz", + "integrity": "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/protobufjs": { + "version": "7.6.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.6.tgz", + "integrity": "sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", + "@protobufjs/float": "^1.0.2", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.3.2" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.1", - "@esbuild/android-arm": "0.28.1", - "@esbuild/android-arm64": "0.28.1", - "@esbuild/android-x64": "0.28.1", - "@esbuild/darwin-arm64": "0.28.1", - "@esbuild/darwin-x64": "0.28.1", - "@esbuild/freebsd-arm64": "0.28.1", - "@esbuild/freebsd-x64": "0.28.1", - "@esbuild/linux-arm": "0.28.1", - "@esbuild/linux-arm64": "0.28.1", - "@esbuild/linux-ia32": "0.28.1", - "@esbuild/linux-loong64": "0.28.1", - "@esbuild/linux-mips64el": "0.28.1", - "@esbuild/linux-ppc64": "0.28.1", - "@esbuild/linux-riscv64": "0.28.1", - "@esbuild/linux-s390x": "0.28.1", - "@esbuild/linux-x64": "0.28.1", - "@esbuild/netbsd-arm64": "0.28.1", - "@esbuild/netbsd-x64": "0.28.1", - "@esbuild/openbsd-arm64": "0.28.1", - "@esbuild/openbsd-x64": "0.28.1", - "@esbuild/openharmony-arm64": "0.28.1", - "@esbuild/sunos-x64": "0.28.1", - "@esbuild/win32-arm64": "0.28.1", - "@esbuild/win32-ia32": "0.28.1", - "@esbuild/win32-x64": "0.28.1" + "engines": { + "node": ">=12.0.0" } }, - "node_modules/fast-check": { - "version": "4.8.0", + "node_modules/pure-rand": { + "version": "8.4.1", "funding": [ { "type": "individual", @@ -697,134 +3961,438 @@ "url": "https://opencollective.com/fast-check" } ], + "license": "MIT" + }, + "node_modules/read-cmd-shim": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-6.0.0.tgz", + "integrity": "sha512-1zM5HuOfagXCBWMN83fuFI/x+T/UhZ7k+KIzhrHXcQoeX5+7gmaDYjELQHmmzIodumBHeByBJT4QYS7ufAgs7A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/redis": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/redis/-/redis-6.2.1.tgz", + "integrity": "sha512-Z9VHtgYs48PiQC77X9O2Er8Hj4T+5BtFjT91/vi5Is1D04N72cA946ZslM1ImJw8ZctFBZWAVjM7S5wJNeHMpg==", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "pure-rand": "^8.0.0" + "@redis/bloom": "6.2.1", + "@redis/client": "6.2.1", + "@redis/json": "6.2.1", + "@redis/search": "6.2.1", + "@redis/time-series": "6.2.1" + }, + "engines": { + "node": ">= 20.0.0" + } + }, + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/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, + "license": "MIT" + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", + "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.1.tgz", + "integrity": "sha512-endqECJkfhozrXMK5ngu/UAA0xVcVEFdnHJCElGaExypjW+HK5i6zu3NteLoaX/iFbRUbC3+DjttQs0GARr+5w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.1", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.1.1", + "@sigstore/tuf": "^4.0.2", + "@sigstore/verify": "^3.1.1" }, "engines": { - "node": ">=12.17.0" + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/find-my-way-ts": { - "version": "0.1.6", - "license": "MIT" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/socks": { + "version": "2.8.10", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.10.tgz", + "integrity": "sha512-e0VyvkVTwVYViNovRkZ9aodhxVlyoMn7eJhVUPxZ+eK9P/7CBkxvvsBOHqFPEH416726W8tLXXXjKwqgTErrCQ==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "ip-address": "^10.1.1", + "smart-buffer": "^4.2.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/ini": { - "version": "7.0.0", - "license": "ISC", + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, "engines": { - "node": "^22.22.2 || ^24.15.0 || >=26.0.0" + "node": ">= 14" } }, - "node_modules/isexe": { - "version": "2.0.0", - "license": "ISC" + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" }, - "node_modules/json-schema": { - "version": "0.4.0", - "license": "(AFL-2.1 OR BSD-3-Clause)" + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } }, - "node_modules/kubernetes-types": { - "version": "1.30.0", - "license": "Apache-2.0" + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "dev": true, + "license": "CC0-1.0" }, - "node_modules/msgpackr": { - "version": "2.0.4", - "license": "MIT", - "optionalDependencies": { - "msgpackr-extract": "^3.0.4" + "node_modules/ssri": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/msgpackr-extract": { - "version": "3.0.4", - "hasInstallScript": true, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "node-gyp-build-optional-packages": "5.2.2" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, - "bin": { - "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + "engines": { + "node": ">=12" }, - "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/multipasta": { - "version": "0.2.8", - "license": "MIT" - }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.2.2", + "node_modules/string-width-cjs": { + "name": "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==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "detect-libc": "^2.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" + "engines": { + "node": ">=8" } }, - "node_modules/path-key": { - "version": "3.1.1", + "node_modules/string-width-cjs/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==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/pure-rand": { - "version": "8.4.1", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], + "node_modules/string-width-cjs/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==", + "dev": true, "license": "MIT" }, - "node_modules/shebang-command": { - "version": "2.0.0", + "node_modules/string-width-cjs/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==", + "dev": true, "license": "MIT", "dependencies": { - "shebang-regex": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/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==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/tar": { + "version": "7.5.22", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz", + "integrity": "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/toml": { "version": "4.1.2", "license": "MIT", @@ -832,6 +4400,23 @@ "node": ">=20" } }, + "node_modules/treeverse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-3.0.0.tgz", + "integrity": "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, "node_modules/tsx": { "version": "4.23.0", "dev": true, @@ -849,6 +4434,21 @@ "fsevents": "~2.3.3" } }, + "node_modules/tuf-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", + "integrity": "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "4.1.0", + "debug": "^4.4.3", + "make-fetch-happen": "^15.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/typescript": { "version": "6.0.3", "dev": true, @@ -861,11 +4461,28 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "6.28.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.1.tgz", + "integrity": "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/undici-types": { "version": "7.18.2", "dev": true, "license": "MIT" }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, "node_modules/uuid": { "version": "14.0.1", "funding": [ @@ -877,6 +4494,36 @@ "uuid": "dist-node/bin/uuid" } }, + "node_modules/validate-npm-package-name": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz", + "integrity": "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/walk-up-path": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-4.0.0.tgz", + "integrity": "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/which": { "version": "2.0.2", "license": "ISC", @@ -890,6 +4537,149 @@ "node": ">= 8" } }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "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==", + "dev": true, + "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/wrap-ansi-cjs/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/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==", + "dev": true, + "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/wrap-ansi-cjs/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/write-file-atomic": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz", + "integrity": "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==", + "dev": true, + "license": "ISC", + "dependencies": { + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/ws": { + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/yaml": { "version": "2.9.0", "license": "ISC", diff --git a/package.json b/package.json index 593f998..d446385 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "main": "dist/index.mjs", "exports": { ".": "./dist/index.mjs", + "./v2": "./dist/plugin-v2.mjs", "./tui": "./dist/tui.mjs" }, "files": [ @@ -57,6 +58,7 @@ }, "devDependencies": { "@dataforxyz/agent-intercom-core": "git+https://github.com/dataforxyz/agent-intercom-core.git#8316cbab548f422ad11c78ed887fabeef94817c1", + "@opencode/plugin": "^2.0.3", "@types/node": "^24.0.0", "esbuild": "^0.28.1", "tsx": "^4.20.0", diff --git a/provider/protected-service.test.ts b/provider/protected-service.test.ts index e2d9485..073822a 100644 --- a/provider/protected-service.test.ts +++ b/provider/protected-service.test.ts @@ -29,7 +29,7 @@ import { const repositoryRoot = new URL("..", import.meta.url); const generatedProviderUrl = new URL("provider/provider.mjs", repositoryRoot); const buildScriptUrl = new URL("scripts/build-protected-provider.mjs", repositoryRoot); -const ordinaryDistNames = ["broker.mjs", "index.mjs", "plugin.mjs", "tui.mjs"]; +const ordinaryDistNames = ["broker.mjs", "index.mjs", "plugin-v2.mjs", "plugin.mjs", "tui.mjs"]; function generatedProviderBytes(): Buffer { return readFileSync(generatedProviderUrl); diff --git a/scripts/build.mjs b/scripts/build.mjs index e762163..63711bb 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -16,6 +16,12 @@ await Promise.all([ outfile: "dist/plugin.mjs", external: ["@opencode-ai/plugin"], }), + build({ + ...common, + entryPoints: ["opencode/plugin-v2.ts"], + outfile: "dist/plugin-v2.mjs", + external: ["@opencode-ai/plugin", "@opencode/plugin"], + }), build({ ...common, entryPoints: ["opencode/public.ts"], diff --git a/test/package-contents.test.ts b/test/package-contents.test.ts index 56f01f1..d8a2228 100644 --- a/test/package-contents.test.ts +++ b/test/package-contents.test.ts @@ -33,6 +33,7 @@ test("protected provider is neither an export, plugin, executable, nor ordinary assert.equal(packageManifest.main, "dist/index.mjs"); assert.deepEqual(packageManifest.exports, { ".": "./dist/index.mjs", + "./v2": "./dist/plugin-v2.mjs", "./tui": "./dist/tui.mjs", }); assert.equal(packageManifest.bin, undefined); @@ -40,6 +41,7 @@ test("protected provider is neither an export, plugin, executable, nor ordinary assert.doesNotMatch(ordinaryBuild, /protected-provider|provider\/provider\.mjs|provider\/entry\.ts/); assert.deepEqual(Array.from(ordinaryBuild.matchAll(/entryPoints: \["([^"]+)"\]/g), (match) => match[1]), [ "opencode/plugin.ts", + "opencode/plugin-v2.ts", "opencode/public.ts", "opencode/tui.ts", "broker/broker.ts", @@ -49,7 +51,7 @@ test("protected provider is neither an export, plugin, executable, nor ordinary assert.equal(packageManifest.scripts.prepack, "npm run build:protected-provider"); }); -test("ordinary builds retain the shared Core externalizer and exactly four dist bundles", () => { +test("ordinary builds retain the shared Core externalizer and exactly five dist bundles", () => { const ordinaryBuild = readFileSync(new URL("scripts/build.mjs", repositoryRoot), "utf8"); const coreExternalizer = readFileSync(new URL("scripts/core-external.mjs", repositoryRoot), "utf8"); @@ -57,6 +59,7 @@ test("ordinary builds retain the shared Core externalizer and exactly four dist assert.match(ordinaryBuild, /plugins: \[externalizeCorePlugin\]/); assert.deepEqual(Array.from(ordinaryBuild.matchAll(/outfile: "dist\/([^"]+)"/g), (match) => match[1]), [ "plugin.mjs", + "plugin-v2.mjs", "index.mjs", "tui.mjs", "broker.mjs",