From abc51204642ca690c7d2aaa645d7b579ca09256e Mon Sep 17 00:00:00 2001 From: Igor Soarez Date: Sun, 25 Oct 2026 12:30:28 +0000 Subject: pirc-extension 0.1.8 --- NOTICE | 10 +- README.md | 24 ++++ index.js | 398 +++++++++++++++++++++++++++++++++++++++++++++-------------- package.json | 2 +- 4 files changed, 336 insertions(+), 98 deletions(-) diff --git a/NOTICE b/NOTICE index f77d66d..5bce5f5 100644 --- a/NOTICE +++ b/NOTICE @@ -3,7 +3,8 @@ Copyright (c) 2026 Igor Soarez The relay, the pi extension and the code they share (proto/, protocol/, relay-client/) are under the MIT licence in LICENSE. The adapter (adapter/) -is proprietary; see adapter/LICENSE. +is proprietary; see adapter/LICENSE. The web app (web/) is proprietary for +now; see web/LICENSE. Code adapted from other projects -------------------------------- @@ -38,3 +39,10 @@ The pi extension and the adapter (JavaScript bundles): - ws 8.22.0, Copyright (c) 2011 Einar Otto Stangvik, (c) 2013 Arnout Kazemier and contributors, (c) 2016 Luigi Pinca and contributors. MIT: third_party/ws/ + +The web app (its server's JavaScript bundle and its page): far more +packages, so each build lists those it carries, with every licence in +full, in a file written from the bundle itself (sh/licenses.ts): the +release's third-party-licenses.txt for the server, and +page/third-party-licenses.txt for the page, which the server also serves +at /third-party-licenses.txt to every browser it sends the page to. diff --git a/README.md b/README.md index adf34e6..1fbf22d 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,30 @@ enrolled without the command; a relay URL without a token asks for approval. If the relay's certificate is self-signed or from a private CA, set `NODE_EXTRA_CA_CERTS` to the CA's PEM file in the environment pi starts in. +## Where pi runs + +Clients name a session by the terminal it runs in. In tmux, that is the +tmux session and window (found through `$TMUX_PANE`); in +[herdr](https://herdr.dev), the workspace and tab (through its socket). +The names are checked again whenever pi does something: a prompt, a turn +starting or ending, a client's request. So a window renamed while pi sits +idle shows its new name after pi's next turn. + +For any other terminal, or to name sessions your own way, another pi +extension can say where pi runs: + +```ts +pi.events.emit("pirc:place", { kind: "zellij", group: "work", window: "api" }); +pi.events.emit("pirc:place", { display: "deploys" }); // shown as it is +pi.events.emit("pirc:place", {}); // show nothing +pi.events.emit("pirc:place", null); // back to PiRC's own detection +``` + +Fields: `kind`, `group` (a tmux session, a workspace), `groupNumber`, +`window` (a window, a tab), `windowNumber`, `pane` and `display`, each +optional; names are cut to 128 bytes. A place given this way stands until +the next one, so the extension can update it whenever it likes. + ## Licence MIT; see `LICENSE`. The bundle includes third-party code, listed in diff --git a/index.js b/index.js index d7ff2b8..d809887 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ -// PiRC extension 0.1.3. Third-party code in this file: @bufbuild/protobuf@2.16.0, ws@8.22.0; see NOTICE. +// PiRC extension 0.1.8. Third-party code in this file: @bufbuild/protobuf@2.16.0, ws@8.22.0; see NOTICE. import { createRequire as __pircCreateRequire } from "node:module"; const require = __pircCreateRequire(import.meta.url); var __create = Object.create; @@ -22,9 +22,9 @@ var __commonJS = (cb, mod) => function __require2() { }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + for (let key2 of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key2) && key2 !== except) + __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable }); } return to; }; @@ -370,44 +370,44 @@ var require_permessage_deflate = __commonJS({ */ normalizeParams(configurations) { configurations.forEach((params) => { - Object.keys(params).forEach((key) => { - let value = params[key]; + Object.keys(params).forEach((key2) => { + let value = params[key2]; if (value.length > 1) { - throw new Error(`Parameter "${key}" must have only a single value`); + throw new Error(`Parameter "${key2}" must have only a single value`); } value = value[0]; - if (key === "client_max_window_bits") { + if (key2 === "client_max_window_bits") { if (value !== true) { - const num = +value; - if (!Number.isInteger(num) || num < 8 || num > 15) { + const num2 = +value; + if (!Number.isInteger(num2) || num2 < 8 || num2 > 15) { throw new TypeError( - `Invalid value for parameter "${key}": ${value}` + `Invalid value for parameter "${key2}": ${value}` ); } - value = num; + value = num2; } else if (!this._isServer) { throw new TypeError( - `Invalid value for parameter "${key}": ${value}` + `Invalid value for parameter "${key2}": ${value}` ); } - } else if (key === "server_max_window_bits") { - const num = +value; - if (!Number.isInteger(num) || num < 8 || num > 15) { + } else if (key2 === "server_max_window_bits") { + const num2 = +value; + if (!Number.isInteger(num2) || num2 < 8 || num2 > 15) { throw new TypeError( - `Invalid value for parameter "${key}": ${value}` + `Invalid value for parameter "${key2}": ${value}` ); } - value = num; - } else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") { + value = num2; + } else if (key2 === "client_no_context_takeover" || key2 === "server_no_context_takeover") { if (value !== true) { throw new TypeError( - `Invalid value for parameter "${key}": ${value}` + `Invalid value for parameter "${key2}": ${value}` ); } } else { - throw new Error(`Unknown parameter "${key}"`); + throw new Error(`Unknown parameter "${key2}"`); } - params[key] = value; + params[key2] = value; }); }); return configurations; @@ -455,8 +455,8 @@ var require_permessage_deflate = __commonJS({ _decompress(data, fin, callback) { const endpoint = this._isServer ? "client" : "server"; if (!this._inflate) { - const key = `${endpoint}_max_window_bits`; - const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key]; + const key2 = `${endpoint}_max_window_bits`; + const windowBits = typeof this.params[key2] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key2]; this._inflate = zlib.createInflateRaw({ ...this._options.zlibInflateOptions, windowBits @@ -506,8 +506,8 @@ var require_permessage_deflate = __commonJS({ _compress(data, fin, callback) { const endpoint = this._isServer ? "server" : "client"; if (!this._deflate) { - const key = `${endpoint}_max_window_bits`; - const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key]; + const key2 = `${endpoint}_max_window_bits`; + const windowBits = typeof this.params[key2] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key2]; this._deflate = zlib.createDeflateRaw({ ...this._options.zlibDeflateOptions, windowBits @@ -1111,8 +1111,8 @@ var require_receiver = __commonJS({ return; } const buf = this.consume(8); - const num = buf.readUInt32BE(0); - if (num > Math.pow(2, 53 - 32) - 1) { + const num2 = buf.readUInt32BE(0); + if (num2 > Math.pow(2, 53 - 32) - 1) { const error = this.createError( RangeError, "Unsupported WebSocket frame: payload length > 2^53 - 1", @@ -1123,7 +1123,7 @@ var require_receiver = __commonJS({ cb(error); return; } - this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4); + this._payloadLength = num2 * Math.pow(2, 32) + buf.readUInt32BE(4); this.haveLength(cb); } /** @@ -2827,7 +2827,7 @@ var require_websocket = __commonJS({ } } const defaultPort = isSecure ? 443 : 80; - const key = randomBytes4(16).toString("base64"); + const key2 = randomBytes4(16).toString("base64"); const request = isSecure ? https.request : http.request; const protocolSet = /* @__PURE__ */ new Set(); let perMessageDeflate; @@ -2838,7 +2838,7 @@ var require_websocket = __commonJS({ opts.headers = { ...opts.headers, "Sec-WebSocket-Version": opts.protocolVersion, - "Sec-WebSocket-Key": key, + "Sec-WebSocket-Key": key2, Connection: "Upgrade", Upgrade: "websocket" }; @@ -2889,8 +2889,8 @@ var require_websocket = __commonJS({ const headers = options && options.headers; options = { ...options, headers: {} }; if (headers) { - for (const [key2, value] of Object.entries(headers)) { - options.headers[key2.toLowerCase()] = value; + for (const [key3, value] of Object.entries(headers)) { + options.headers[key3.toLowerCase()] = value; } } } else if (websocket.listenerCount("redirect") === 0) { @@ -2957,7 +2957,7 @@ var require_websocket = __commonJS({ abortHandshake(websocket, socket, "Invalid Upgrade header"); return; } - const digest = createHash("sha1").update(key + GUID).digest("base64"); + const digest = createHash("sha1").update(key2 + GUID).digest("base64"); if (res.headers["sec-websocket-accept"] !== digest) { abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header"); return; @@ -3525,7 +3525,7 @@ var require_websocket_server = __commonJS({ */ handleUpgrade(req, socket, head, cb) { socket.on("error", socketOnError); - const key = req.headers["sec-websocket-key"]; + const key2 = req.headers["sec-websocket-key"]; const upgrade = req.headers.upgrade; const version = +req.headers["sec-websocket-version"]; if (req.method !== "GET") { @@ -3538,7 +3538,7 @@ var require_websocket_server = __commonJS({ abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); return; } - if (key === void 0 || !keyRegex.test(key)) { + if (key2 === void 0 || !keyRegex.test(key2)) { const message = "Missing or invalid Sec-WebSocket-Key header"; abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); return; @@ -3598,7 +3598,7 @@ var require_websocket_server = __commonJS({ } this.completeUpgrade( extensions, - key, + key2, protocols, req, socket, @@ -3610,7 +3610,7 @@ var require_websocket_server = __commonJS({ } if (!this.options.verifyClient(info)) return abortHandshake(socket, 401); } - this.completeUpgrade(extensions, key, protocols, req, socket, head, cb); + this.completeUpgrade(extensions, key2, protocols, req, socket, head, cb); } /** * Upgrade the connection to WebSocket. @@ -3625,7 +3625,7 @@ var require_websocket_server = __commonJS({ * @throws {Error} If called more than once with the same socket * @private */ - completeUpgrade(extensions, key, protocols, req, socket, head, cb) { + completeUpgrade(extensions, key2, protocols, req, socket, head, cb) { if (!socket.readable || !socket.writable) return socket.destroy(); if (socket[kWebSocket]) { throw new Error( @@ -3633,7 +3633,7 @@ var require_websocket_server = __commonJS({ ); } if (this._state > RUNNING) return abortHandshake(socket, 503); - const digest = createHash("sha1").update(key + GUID).digest("base64"); + const digest = createHash("sha1").update(key2 + GUID).digest("base64"); const headers = [ "HTTP/1.1 101 Switching Protocols", "Upgrade: websocket", @@ -4055,8 +4055,8 @@ function scalarZeroValue(type, longAsString) { function unsafeIsSetExplicit(target, localName) { return Object.prototype.hasOwnProperty.call(target, localName) && target[localName] !== void 0; } -function setOwn(obj, key, value) { - if (key === "__proto__") { +function setOwn(obj, key2, value) { + if (key2 === "__proto__") { Object.defineProperty(obj, "__proto__", { value, writable: true, @@ -4064,7 +4064,7 @@ function setOwn(obj, key, value) { configurable: true }); } else { - obj[key] = value; + obj[key2] = value; } } @@ -5924,8 +5924,8 @@ function newField(proto, parentOrFile, reg, oneof, mapEntries) { const mapEntry = type == TYPE_MESSAGE ? mapEntries === null || mapEntries === void 0 ? void 0 : mapEntries.get(trimLeadingDot(proto.typeName)) : void 0; if (mapEntry) { field.fieldKind = "map"; - const { key, value } = findMapEntryFields(mapEntry); - field.mapKey = key.scalar; + const { key: key2, value } = findMapEntryFields(mapEntry); + field.mapKey = key2.scalar; field.mapKind = value.fieldKind; field.message = value.message; field.delimitedEncoding = false; @@ -6120,10 +6120,10 @@ function isPackedField(proto, parent) { }); } function findMapEntryFields(mapEntry) { - const key = mapEntry.fields.find((f) => f.number === 1); + const key2 = mapEntry.fields.find((f) => f.number === 1); const value = mapEntry.fields.find((f) => f.number === 2); - assert(key && key.fieldKind == "scalar" && key.scalar != ScalarType.BYTES && key.scalar != ScalarType.FLOAT && key.scalar != ScalarType.DOUBLE && value && value.fieldKind != "list" && value.fieldKind != "map"); - return { key, value }; + assert(key2 && key2.fieldKind == "scalar" && key2.scalar != ScalarType.BYTES && key2.scalar != ScalarType.FLOAT && key2.scalar != ScalarType.DOUBLE && value && value.fieldKind != "list" && value.fieldKind != "map"); + return { key: key2, value }; } function isEnumOpen(desc) { var _a; @@ -6667,7 +6667,7 @@ function compileMapFieldReader(field) { } return (message, reader, ctx) => { const record = message[localName]; - let key; + let key2; let val; const len = reader.uint32(); const end = reader.pos + len; @@ -6675,20 +6675,20 @@ function compileMapFieldReader(field) { const [fieldNo] = reader.tag(); switch (fieldNo) { case 1: - key = readKey(reader); + key2 = readKey(reader); break; case 2: val = readValue(reader, ctx, val); break; } } - if (key === void 0) { - key = keyZero; + if (key2 === void 0) { + key2 = keyZero; } if (val === void 0) { val = valueDefault(); } - setOwn(record, key, val); + setOwn(record, key2, val); }; } function compileScalarReader(type, utf8Validation, longAsString) { @@ -6973,11 +6973,11 @@ function compileMapField(field) { const record = message[localName]; const keys = Object.keys(record); for (let i = 0; i < keys.length; i++) { - const key = keys[i]; + const key2 = keys[i]; writer.tag(fieldNo, WireType.LengthDelimited).fork(); - writeKey(writer, key); + writeKey(writer, key2); writer.tag(2, WireType.LengthDelimited).fork(); - writeMessage(writer, opts, toMessage(record[key])); + writeMessage(writer, opts, toMessage(record[key2])); writer.join(); writer.join(); } @@ -6990,11 +6990,11 @@ function compileMapField(field) { const record = message[localName]; const keys = Object.keys(record); for (let i = 0; i < keys.length; i++) { - const key = keys[i]; + const key2 = keys[i]; writer.tag(fieldNo, WireType.LengthDelimited).fork(); - writeKey(writer, key); + writeKey(writer, key2); writer.tag(2, valueWireType); - writeScalar(writer, record[key]); + writeScalar(writer, record[key2]); writer.join(); } }; @@ -7003,40 +7003,40 @@ function compileMapKey(field) { const wireType = writeTypeOfScalar(field.mapKey); const writeScalar = compileScalarValue(field.mapKey, field.parent.typeName, field.name); const convertKey = compileMapKeyConverter(field.mapKey); - return (writer, key) => { + return (writer, key2) => { writer.tag(1, wireType); - writeScalar(writer, convertKey(key)); + writeScalar(writer, convertKey(key2)); }; } function compileMapKeyConverter(type) { switch (type) { case ScalarType.STRING: - return (key) => key; + return (key2) => key2; case ScalarType.BOOL: - return (key) => key === "true" ? true : key === "false" ? false : key; + return (key2) => key2 === "true" ? true : key2 === "false" ? false : key2; case ScalarType.UINT64: case ScalarType.FIXED64: - return (key) => { + return (key2) => { try { - return protoInt64.uParse(key); + return protoInt64.uParse(key2); } catch (_a) { - return key; + return key2; } }; case ScalarType.INT64: case ScalarType.SFIXED64: case ScalarType.SINT64: - return (key) => { + return (key2) => { try { - return protoInt64.parse(key); + return protoInt64.parse(key2); } catch (_a) { - return key; + return key2; } }; default: - return (key) => { - const n = Number.parseInt(key); - return Number.isFinite(n) ? n : key; + return (key2) => { + const n = Number.parseInt(key2); + return Number.isFinite(n) ? n : key2; }; } } @@ -7140,16 +7140,17 @@ var file_pirc_v1alpha1_relay = /* @__PURE__ */ fileDesc("ChlwaXJjL3YxYWxwaGExL3J var FrameSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_relay, 0); // protocol/gen/pirc/v1alpha1/session_pb.ts -var file_pirc_v1alpha1_session = /* @__PURE__ */ fileDesc("ChtwaXJjL3YxYWxwaGExL3Nlc3Npb24ucHJvdG8SDXBpcmMudjFhbHBoYTEi7AIKE1Nlc3Npb25Bbm5vdW5jZW1lbnQSDAoEbmFtZRgBIAEoCRILCgNjd2QYAiABKAkSEAoIaG9zdG5hbWUYAyABKAkSIwoFbW9kZWwYBCABKAsyFC5waXJjLnYxYWxwaGExLk1vZGVsEjQKDnRoaW5raW5nX2xldmVsGAUgASgOMhwucGlyYy52MWFscGhhMS5UaGlua2luZ0xldmVsEg8KB3dvcmtpbmcYBiABKAgSLgoKc3RhcnRlZF9hdBgHIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASGwoTcmVwbGFjZXNfc2Vzc2lvbl9pZBgIIAEoCRIsCgZvcmlnaW4YCSABKA4yHC5waXJjLnYxYWxwaGExLlNlc3Npb25PcmlnaW4SEgoKcGlfdmVyc2lvbhgKIAEoCRIZChFleHRlbnNpb25fdmVyc2lvbhgLIAEoCRISCgpjb21wYWN0aW5nGAwgASgIIjMKBU1vZGVsEhAKCHByb3ZpZGVyGAEgASgJEgoKAmlkGAIgASgJEgwKBG5hbWUYAyABKAki3QYKDlNlc3Npb25NZXNzYWdlEicKBnByb21wdBgBIAEoCzIVLnBpcmMudjFhbHBoYTEuUHJvbXB0SAASJQoFYWJvcnQYAiABKAsyFC5waXJjLnYxYWxwaGExLkFib3J0SAASOAoPaGlzdG9yeV9yZXF1ZXN0GAMgASgLMh0ucGlyYy52MWFscGhhMS5IaXN0b3J5UmVxdWVzdEgAEjAKC2xpc3RfbW9kZWxzGAQgASgLMhkucGlyYy52MWFscGhhMS5MaXN0TW9kZWxzSAASLAoJc2V0X21vZGVsGAUgASgLMhcucGlyYy52MWFscGhhMS5TZXRNb2RlbEgAEj0KEnNldF90aGlua2luZ19sZXZlbBgGIAEoCzIfLnBpcmMudjFhbHBoYTEuU2V0VGhpbmtpbmdMZXZlbEgAEikKB2NvbXBhY3QYByABKAsyFi5waXJjLnYxYWxwaGExLkNvbXBhY3RIABIwCgtuZXdfc2Vzc2lvbhgIIAEoCzIZLnBpcmMudjFhbHBoYTEuTmV3U2Vzc2lvbkgAEicKBnJlbmFtZRgJIAEoCzIVLnBpcmMudjFhbHBoYTEuUmVuYW1lSAASNAoNc3RhdHNfcmVxdWVzdBgRIAEoCzIbLnBpcmMudjFhbHBoYTEuU3RhdHNSZXF1ZXN0SAASNAoNbGlzdF9jb21tYW5kcxgSIAEoCzIbLnBpcmMudjFhbHBoYTEuTGlzdENvbW1hbmRzSAASLAoFZXZlbnQYCiABKAsyGy5waXJjLnYxYWxwaGExLlNlc3Npb25FdmVudEgAEikKB2hpc3RvcnkYCyABKAsyFi5waXJjLnYxYWxwaGExLkhpc3RvcnlIABIrCghhY2NlcHRlZBgMIAEoCzIXLnBpcmMudjFhbHBoYTEuQWNjZXB0ZWRIABIlCgVlcnJvchgNIAEoCzIULnBpcmMudjFhbHBoYTEuRXJyb3JIABInCgZtb2RlbHMYDiABKAsyFS5waXJjLnYxYWxwaGExLk1vZGVsc0gAEiUKBXN0YXRzGA8gASgLMhQucGlyYy52MWFscGhhMS5TdGF0c0gAEisKCGNvbW1hbmRzGBAgASgLMhcucGlyYy52MWFscGhhMS5Db21tYW5kc0gAQgYKBGJvZHkiIAoKTGlzdE1vZGVscxISCgpyZXF1ZXN0X2lkGAEgASgJInEKBk1vZGVscxISCgpyZXF1ZXN0X2lkGAEgASgJEigKBm1vZGVscxgCIAMoCzIYLnBpcmMudjFhbHBoYTEuTW9kZWxJbmZvEikKB2N1cnJlbnQYAyABKAsyGC5waXJjLnYxYWxwaGExLk1vZGVsSW5mbyJrCglNb2RlbEluZm8SIwoFbW9kZWwYASABKAsyFC5waXJjLnYxYWxwaGExLk1vZGVsEhEKCXJlYXNvbmluZxgCIAEoCBIWCg5jb250ZXh0X3dpbmRvdxgDIAEoBBIOCgZpbWFnZXMYBCABKAgiQwoIU2V0TW9kZWwSEgoKcmVxdWVzdF9pZBgBIAEoCRIjCgVtb2RlbBgCIAEoCzIULnBpcmMudjFhbHBoYTEuTW9kZWwiUwoQU2V0VGhpbmtpbmdMZXZlbBISCgpyZXF1ZXN0X2lkGAEgASgJEisKBWxldmVsGAIgASgOMhwucGlyYy52MWFscGhhMS5UaGlua2luZ0xldmVsIjMKB0NvbXBhY3QSEgoKcmVxdWVzdF9pZBgBIAEoCRIUCgxpbnN0cnVjdGlvbnMYAiABKAkiIAoKTmV3U2Vzc2lvbhISCgpyZXF1ZXN0X2lkGAEgASgJIioKBlJlbmFtZRISCgpyZXF1ZXN0X2lkGAEgASgJEgwKBG5hbWUYAiABKAkiIgoMU3RhdHNSZXF1ZXN0EhIKCnJlcXVlc3RfaWQYASABKAkiiAEKBVN0YXRzEhIKCnJlcXVlc3RfaWQYASABKAkSIwoFdG90YWwYAiABKAsyFC5waXJjLnYxYWxwaGExLlVzYWdlEhsKDmNvbnRleHRfdG9rZW5zGAMgASgESACIAQESFgoOY29udGV4dF93aW5kb3cYBCABKARCEQoPX2NvbnRleHRfdG9rZW5zIiIKDExpc3RDb21tYW5kcxISCgpyZXF1ZXN0X2lkGAEgASgJIkwKCENvbW1hbmRzEhIKCnJlcXVlc3RfaWQYASABKAkSLAoIY29tbWFuZHMYAiADKAsyGi5waXJjLnYxYWxwaGExLkNvbW1hbmRJbmZvIl4KC0NvbW1hbmRJbmZvEgwKBG5hbWUYASABKAkSEwoLZGVzY3JpcHRpb24YAiABKAkSLAoGc291cmNlGAMgASgOMhwucGlyYy52MWFscGhhMS5Db21tYW5kU291cmNlInsKBlByb21wdBISCgpyZXF1ZXN0X2lkGAEgASgJEgwKBHRleHQYAiABKAkSJAoGaW1hZ2VzGAMgAygLMhQucGlyYy52MWFscGhhMS5JbWFnZRIpCghkZWxpdmVyeRgEIAEoDjIXLnBpcmMudjFhbHBoYTEuRGVsaXZlcnkiKAoFSW1hZ2USEQoJbWltZV90eXBlGAEgASgJEgwKBGRhdGEYAiABKAwiGwoFQWJvcnQSEgoKcmVxdWVzdF9pZBgBIAEoCSIzCg5IaXN0b3J5UmVxdWVzdBISCgpyZXF1ZXN0X2lkGAEgASgJEg0KBWxpbWl0GAIgASgNIm0KB0hpc3RvcnkSEgoKcmVxdWVzdF9pZBgBIAEoCRIuCgVpdGVtcxgCIAMoCzIfLnBpcmMudjFhbHBoYTEuQ29udmVyc2F0aW9uSXRlbRILCgNzZXEYAyABKAQSEQoJdHJ1bmNhdGVkGAQgASgIIh4KCEFjY2VwdGVkEhIKCnJlcXVlc3RfaWQYASABKAki4gIKDFNlc3Npb25FdmVudBILCgNzZXEYASABKAQSJgoCYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KBGl0ZW0YAyABKAsyHy5waXJjLnYxYWxwaGExLkNvbnZlcnNhdGlvbkl0ZW1IABI4Cg9hc3Npc3RhbnRfZGVsdGEYBCABKAsyHS5waXJjLnYxYWxwaGExLkFzc2lzdGFudERlbHRhSAASNAoNdG9vbF9wcm9ncmVzcxgFIAEoCzIbLnBpcmMudjFhbHBoYTEuVG9vbFByb2dyZXNzSAASOAoPd29ya2luZ19jaGFuZ2VkGAYgASgLMh0ucGlyYy52MWFscGhhMS5Xb3JraW5nQ2hhbmdlZEgAEjoKDGFubm91bmNlbWVudBgHIAEoCzIiLnBpcmMudjFhbHBoYTEuU2Vzc2lvbkFubm91bmNlbWVudEgAQgYKBGJvZHki6AIKEENvbnZlcnNhdGlvbkl0ZW0SEAoIZW50cnlfaWQYASABKAkSDwoHdHVybl9pZBgCIAEoCRImCgJhdBgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASMgoMdXNlcl9tZXNzYWdlGAQgASgLMhoucGlyYy52MWFscGhhMS5Vc2VyTWVzc2FnZUgAEjwKEWFzc2lzdGFudF9tZXNzYWdlGAUgASgLMh8ucGlyYy52MWFscGhhMS5Bc3Npc3RhbnRNZXNzYWdlSAASLAoJdG9vbF9jYWxsGAYgASgLMhcucGlyYy52MWFscGhhMS5Ub29sQ2FsbEgAEjAKC3Rvb2xfcmVzdWx0GAcgASgLMhkucGlyYy52MWFscGhhMS5Ub29sUmVzdWx0SAASLwoKY29tcGFjdGlvbhgIIAEoCzIZLnBpcmMudjFhbHBoYTEuQ29tcGFjdGlvbkgAQgYKBGJvZHkiVQoLVXNlck1lc3NhZ2USDAoEdGV4dBgBIAEoCRIkCgZpbWFnZXMYAiADKAsyFC5waXJjLnYxYWxwaGExLkltYWdlEhIKCnJlcXVlc3RfaWQYAyABKAki5QEKEEFzc2lzdGFudE1lc3NhZ2USEgoKbWVzc2FnZV9pZBgBIAEoCRIsCgdjb250ZW50GAIgAygLMhsucGlyYy52MWFscGhhMS5Db250ZW50QmxvY2sSIwoFdXNhZ2UYAyABKAsyFC5waXJjLnYxYWxwaGExLlVzYWdlEi4KC3N0b3BfcmVhc29uGAQgASgOMhkucGlyYy52MWFscGhhMS5TdG9wUmVhc29uEiMKBW1vZGVsGAUgASgLMhQucGlyYy52MWFscGhhMS5Nb2RlbBIVCg1lcnJvcl9tZXNzYWdlGAYgASgJIjoKDENvbnRlbnRCbG9jaxIOCgR0ZXh0GAEgASgJSAASEgoIdGhpbmtpbmcYAiABKAlIAEIGCgRib2R5InkKBVVzYWdlEhQKDGlucHV0X3Rva2VucxgBIAEoBBIVCg1vdXRwdXRfdG9rZW5zGAIgASgEEhkKEWNhY2hlX3JlYWRfdG9rZW5zGAMgASgEEhoKEmNhY2hlX3dyaXRlX3Rva2VucxgEIAEoBBIMCgRjb3N0GAUgASgBInYKDkFzc2lzdGFudERlbHRhEhIKCm1lc3NhZ2VfaWQYASABKAkSDwoHdHVybl9pZBgCIAEoCRITCgtibG9ja19pbmRleBgDIAEoDRIOCgR0ZXh0GAQgASgJSAASEgoIdGhpbmtpbmcYBSABKAlIAEIGCgRib2R5IksKCFRvb2xDYWxsEhQKDHRvb2xfY2FsbF9pZBgBIAEoCRIRCgl0b29sX25hbWUYAiABKAkSFgoOYXJndW1lbnRzX2pzb24YAyABKAkiQgoKVG9vbFJlc3VsdBIUCgx0b29sX2NhbGxfaWQYASABKAkSEAoIaXNfZXJyb3IYAiABKAgSDAoEdGV4dBgDIAEoCSJDCgxUb29sUHJvZ3Jlc3MSFAoMdG9vbF9jYWxsX2lkGAEgASgJEg8KB3R1cm5faWQYAiABKAkSDAoEdGV4dBgDIAEoCSIhCg5Xb3JraW5nQ2hhbmdlZBIPCgd3b3JraW5nGAEgASgIIjQKCkNvbXBhY3Rpb24SDwoHc3VtbWFyeRgBIAEoCRIVCg10b2tlbnNfYmVmb3JlGAIgASgEKrIBCg1TZXNzaW9uT3JpZ2luEh4KGlNFU1NJT05fT1JJR0lOX1VOU1BFQ0lGSUVEEAASGgoWU0VTU0lPTl9PUklHSU5fU1RBUlRVUBABEhYKElNFU1NJT05fT1JJR0lOX05FVxACEhkKFVNFU1NJT05fT1JJR0lOX1JFU1VNRRADEhcKE1NFU1NJT05fT1JJR0lOX0ZPUksQBBIZChVTRVNTSU9OX09SSUdJTl9SRUxPQUQQBSrhAQoNVGhpbmtpbmdMZXZlbBIeChpUSElOS0lOR19MRVZFTF9VTlNQRUNJRklFRBAAEhYKElRISU5LSU5HX0xFVkVMX09GRhABEhoKFlRISU5LSU5HX0xFVkVMX01JTklNQUwQAhIWChJUSElOS0lOR19MRVZFTF9MT1cQAxIZChVUSElOS0lOR19MRVZFTF9NRURJVU0QBBIXChNUSElOS0lOR19MRVZFTF9ISUdIEAUSGAoUVEhJTktJTkdfTEVWRUxfWEhJR0gQBhIWChJUSElOS0lOR19MRVZFTF9NQVgQByqCAQoNQ29tbWFuZFNvdXJjZRIeChpDT01NQU5EX1NPVVJDRV9VTlNQRUNJRklFRBAAEhwKGENPTU1BTkRfU09VUkNFX0VYVEVOU0lPThABEhkKFUNPTU1BTkRfU09VUkNFX1BST01QVBACEhgKFENPTU1BTkRfU09VUkNFX1NLSUxMEAMqUAoIRGVsaXZlcnkSGAoUREVMSVZFUllfVU5TUEVDSUZJRUQQABISCg5ERUxJVkVSWV9TVEVFUhABEhYKEkRFTElWRVJZX0ZPTExPV19VUBACKrsBCgpTdG9wUmVhc29uEhsKF1NUT1BfUkVBU09OX1VOU1BFQ0lGSUVEEAASFAoQU1RPUF9SRUFTT05fU1RPUBABEhYKElNUT1BfUkVBU09OX0xFTkdUSBACEhgKFFNUT1BfUkVBU09OX1RPT0xfVVNFEAMSFwoTU1RPUF9SRUFTT05fQUJPUlRFRBAEEhUKEVNUT1BfUkVBU09OX0VSUk9SEAUSGAoUU1RPUF9SRUFTT05fREVGRVJSRUQQBkKtAQoRY29tLnBpcmMudjFhbHBoYTFCDFNlc3Npb25Qcm90b1ABWjVwaXJjLmRldi9yZWxheS9pbnRlcm5hbC9wYi9waXJjL3YxYWxwaGExO3BpcmN2MWFscGhhMaICA1BYWKoCDVBpcmMuVjFhbHBoYTHKAg1QaXJjXFYxYWxwaGEx4gIZUGlyY1xWMWFscGhhMVxHUEJNZXRhZGF0YeoCDlBpcmM6OlYxYWxwaGExYgZwcm90bzM", [file_google_protobuf_timestamp, file_pirc_v1alpha1_common]); +var file_pirc_v1alpha1_session = /* @__PURE__ */ fileDesc("ChtwaXJjL3YxYWxwaGExL3Nlc3Npb24ucHJvdG8SDXBpcmMudjFhbHBoYTEikQMKE1Nlc3Npb25Bbm5vdW5jZW1lbnQSDAoEbmFtZRgBIAEoCRILCgNjd2QYAiABKAkSEAoIaG9zdG5hbWUYAyABKAkSIwoFbW9kZWwYBCABKAsyFC5waXJjLnYxYWxwaGExLk1vZGVsEjQKDnRoaW5raW5nX2xldmVsGAUgASgOMhwucGlyYy52MWFscGhhMS5UaGlua2luZ0xldmVsEg8KB3dvcmtpbmcYBiABKAgSLgoKc3RhcnRlZF9hdBgHIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASGwoTcmVwbGFjZXNfc2Vzc2lvbl9pZBgIIAEoCRIsCgZvcmlnaW4YCSABKA4yHC5waXJjLnYxYWxwaGExLlNlc3Npb25PcmlnaW4SEgoKcGlfdmVyc2lvbhgKIAEoCRIZChFleHRlbnNpb25fdmVyc2lvbhgLIAEoCRISCgpjb21wYWN0aW5nGAwgASgIEiMKBXBsYWNlGA0gASgLMhQucGlyYy52MWFscGhhMS5QbGFjZSKtAQoFUGxhY2USDAoEa2luZBgBIAEoCRINCgVncm91cBgCIAEoCRIZCgxncm91cF9udW1iZXIYAyABKA1IAIgBARIOCgZ3aW5kb3cYBCABKAkSGgoNd2luZG93X251bWJlchgFIAEoDUgBiAEBEgwKBHBhbmUYBiABKAkSDwoHZGlzcGxheRgHIAEoCUIPCg1fZ3JvdXBfbnVtYmVyQhAKDl93aW5kb3dfbnVtYmVyIjMKBU1vZGVsEhAKCHByb3ZpZGVyGAEgASgJEgoKAmlkGAIgASgJEgwKBG5hbWUYAyABKAki3QYKDlNlc3Npb25NZXNzYWdlEicKBnByb21wdBgBIAEoCzIVLnBpcmMudjFhbHBoYTEuUHJvbXB0SAASJQoFYWJvcnQYAiABKAsyFC5waXJjLnYxYWxwaGExLkFib3J0SAASOAoPaGlzdG9yeV9yZXF1ZXN0GAMgASgLMh0ucGlyYy52MWFscGhhMS5IaXN0b3J5UmVxdWVzdEgAEjAKC2xpc3RfbW9kZWxzGAQgASgLMhkucGlyYy52MWFscGhhMS5MaXN0TW9kZWxzSAASLAoJc2V0X21vZGVsGAUgASgLMhcucGlyYy52MWFscGhhMS5TZXRNb2RlbEgAEj0KEnNldF90aGlua2luZ19sZXZlbBgGIAEoCzIfLnBpcmMudjFhbHBoYTEuU2V0VGhpbmtpbmdMZXZlbEgAEikKB2NvbXBhY3QYByABKAsyFi5waXJjLnYxYWxwaGExLkNvbXBhY3RIABIwCgtuZXdfc2Vzc2lvbhgIIAEoCzIZLnBpcmMudjFhbHBoYTEuTmV3U2Vzc2lvbkgAEicKBnJlbmFtZRgJIAEoCzIVLnBpcmMudjFhbHBoYTEuUmVuYW1lSAASNAoNc3RhdHNfcmVxdWVzdBgRIAEoCzIbLnBpcmMudjFhbHBoYTEuU3RhdHNSZXF1ZXN0SAASNAoNbGlzdF9jb21tYW5kcxgSIAEoCzIbLnBpcmMudjFhbHBoYTEuTGlzdENvbW1hbmRzSAASLAoFZXZlbnQYCiABKAsyGy5waXJjLnYxYWxwaGExLlNlc3Npb25FdmVudEgAEikKB2hpc3RvcnkYCyABKAsyFi5waXJjLnYxYWxwaGExLkhpc3RvcnlIABIrCghhY2NlcHRlZBgMIAEoCzIXLnBpcmMudjFhbHBoYTEuQWNjZXB0ZWRIABIlCgVlcnJvchgNIAEoCzIULnBpcmMudjFhbHBoYTEuRXJyb3JIABInCgZtb2RlbHMYDiABKAsyFS5waXJjLnYxYWxwaGExLk1vZGVsc0gAEiUKBXN0YXRzGA8gASgLMhQucGlyYy52MWFscGhhMS5TdGF0c0gAEisKCGNvbW1hbmRzGBAgASgLMhcucGlyYy52MWFscGhhMS5Db21tYW5kc0gAQgYKBGJvZHkiIAoKTGlzdE1vZGVscxISCgpyZXF1ZXN0X2lkGAEgASgJInEKBk1vZGVscxISCgpyZXF1ZXN0X2lkGAEgASgJEigKBm1vZGVscxgCIAMoCzIYLnBpcmMudjFhbHBoYTEuTW9kZWxJbmZvEikKB2N1cnJlbnQYAyABKAsyGC5waXJjLnYxYWxwaGExLk1vZGVsSW5mbyJrCglNb2RlbEluZm8SIwoFbW9kZWwYASABKAsyFC5waXJjLnYxYWxwaGExLk1vZGVsEhEKCXJlYXNvbmluZxgCIAEoCBIWCg5jb250ZXh0X3dpbmRvdxgDIAEoBBIOCgZpbWFnZXMYBCABKAgiQwoIU2V0TW9kZWwSEgoKcmVxdWVzdF9pZBgBIAEoCRIjCgVtb2RlbBgCIAEoCzIULnBpcmMudjFhbHBoYTEuTW9kZWwiUwoQU2V0VGhpbmtpbmdMZXZlbBISCgpyZXF1ZXN0X2lkGAEgASgJEisKBWxldmVsGAIgASgOMhwucGlyYy52MWFscGhhMS5UaGlua2luZ0xldmVsIjMKB0NvbXBhY3QSEgoKcmVxdWVzdF9pZBgBIAEoCRIUCgxpbnN0cnVjdGlvbnMYAiABKAkiIAoKTmV3U2Vzc2lvbhISCgpyZXF1ZXN0X2lkGAEgASgJIioKBlJlbmFtZRISCgpyZXF1ZXN0X2lkGAEgASgJEgwKBG5hbWUYAiABKAkiIgoMU3RhdHNSZXF1ZXN0EhIKCnJlcXVlc3RfaWQYASABKAkiiAEKBVN0YXRzEhIKCnJlcXVlc3RfaWQYASABKAkSIwoFdG90YWwYAiABKAsyFC5waXJjLnYxYWxwaGExLlVzYWdlEhsKDmNvbnRleHRfdG9rZW5zGAMgASgESACIAQESFgoOY29udGV4dF93aW5kb3cYBCABKARCEQoPX2NvbnRleHRfdG9rZW5zIiIKDExpc3RDb21tYW5kcxISCgpyZXF1ZXN0X2lkGAEgASgJIkwKCENvbW1hbmRzEhIKCnJlcXVlc3RfaWQYASABKAkSLAoIY29tbWFuZHMYAiADKAsyGi5waXJjLnYxYWxwaGExLkNvbW1hbmRJbmZvIl4KC0NvbW1hbmRJbmZvEgwKBG5hbWUYASABKAkSEwoLZGVzY3JpcHRpb24YAiABKAkSLAoGc291cmNlGAMgASgOMhwucGlyYy52MWFscGhhMS5Db21tYW5kU291cmNlInsKBlByb21wdBISCgpyZXF1ZXN0X2lkGAEgASgJEgwKBHRleHQYAiABKAkSJAoGaW1hZ2VzGAMgAygLMhQucGlyYy52MWFscGhhMS5JbWFnZRIpCghkZWxpdmVyeRgEIAEoDjIXLnBpcmMudjFhbHBoYTEuRGVsaXZlcnkiKAoFSW1hZ2USEQoJbWltZV90eXBlGAEgASgJEgwKBGRhdGEYAiABKAwiGwoFQWJvcnQSEgoKcmVxdWVzdF9pZBgBIAEoCSIzCg5IaXN0b3J5UmVxdWVzdBISCgpyZXF1ZXN0X2lkGAEgASgJEg0KBWxpbWl0GAIgASgNIm0KB0hpc3RvcnkSEgoKcmVxdWVzdF9pZBgBIAEoCRIuCgVpdGVtcxgCIAMoCzIfLnBpcmMudjFhbHBoYTEuQ29udmVyc2F0aW9uSXRlbRILCgNzZXEYAyABKAQSEQoJdHJ1bmNhdGVkGAQgASgIIh4KCEFjY2VwdGVkEhIKCnJlcXVlc3RfaWQYASABKAki4gIKDFNlc3Npb25FdmVudBILCgNzZXEYASABKAQSJgoCYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KBGl0ZW0YAyABKAsyHy5waXJjLnYxYWxwaGExLkNvbnZlcnNhdGlvbkl0ZW1IABI4Cg9hc3Npc3RhbnRfZGVsdGEYBCABKAsyHS5waXJjLnYxYWxwaGExLkFzc2lzdGFudERlbHRhSAASNAoNdG9vbF9wcm9ncmVzcxgFIAEoCzIbLnBpcmMudjFhbHBoYTEuVG9vbFByb2dyZXNzSAASOAoPd29ya2luZ19jaGFuZ2VkGAYgASgLMh0ucGlyYy52MWFscGhhMS5Xb3JraW5nQ2hhbmdlZEgAEjoKDGFubm91bmNlbWVudBgHIAEoCzIiLnBpcmMudjFhbHBoYTEuU2Vzc2lvbkFubm91bmNlbWVudEgAQgYKBGJvZHki6AIKEENvbnZlcnNhdGlvbkl0ZW0SEAoIZW50cnlfaWQYASABKAkSDwoHdHVybl9pZBgCIAEoCRImCgJhdBgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASMgoMdXNlcl9tZXNzYWdlGAQgASgLMhoucGlyYy52MWFscGhhMS5Vc2VyTWVzc2FnZUgAEjwKEWFzc2lzdGFudF9tZXNzYWdlGAUgASgLMh8ucGlyYy52MWFscGhhMS5Bc3Npc3RhbnRNZXNzYWdlSAASLAoJdG9vbF9jYWxsGAYgASgLMhcucGlyYy52MWFscGhhMS5Ub29sQ2FsbEgAEjAKC3Rvb2xfcmVzdWx0GAcgASgLMhkucGlyYy52MWFscGhhMS5Ub29sUmVzdWx0SAASLwoKY29tcGFjdGlvbhgIIAEoCzIZLnBpcmMudjFhbHBoYTEuQ29tcGFjdGlvbkgAQgYKBGJvZHkiVQoLVXNlck1lc3NhZ2USDAoEdGV4dBgBIAEoCRIkCgZpbWFnZXMYAiADKAsyFC5waXJjLnYxYWxwaGExLkltYWdlEhIKCnJlcXVlc3RfaWQYAyABKAki5QEKEEFzc2lzdGFudE1lc3NhZ2USEgoKbWVzc2FnZV9pZBgBIAEoCRIsCgdjb250ZW50GAIgAygLMhsucGlyYy52MWFscGhhMS5Db250ZW50QmxvY2sSIwoFdXNhZ2UYAyABKAsyFC5waXJjLnYxYWxwaGExLlVzYWdlEi4KC3N0b3BfcmVhc29uGAQgASgOMhkucGlyYy52MWFscGhhMS5TdG9wUmVhc29uEiMKBW1vZGVsGAUgASgLMhQucGlyYy52MWFscGhhMS5Nb2RlbBIVCg1lcnJvcl9tZXNzYWdlGAYgASgJIjoKDENvbnRlbnRCbG9jaxIOCgR0ZXh0GAEgASgJSAASEgoIdGhpbmtpbmcYAiABKAlIAEIGCgRib2R5InkKBVVzYWdlEhQKDGlucHV0X3Rva2VucxgBIAEoBBIVCg1vdXRwdXRfdG9rZW5zGAIgASgEEhkKEWNhY2hlX3JlYWRfdG9rZW5zGAMgASgEEhoKEmNhY2hlX3dyaXRlX3Rva2VucxgEIAEoBBIMCgRjb3N0GAUgASgBInYKDkFzc2lzdGFudERlbHRhEhIKCm1lc3NhZ2VfaWQYASABKAkSDwoHdHVybl9pZBgCIAEoCRITCgtibG9ja19pbmRleBgDIAEoDRIOCgR0ZXh0GAQgASgJSAASEgoIdGhpbmtpbmcYBSABKAlIAEIGCgRib2R5IksKCFRvb2xDYWxsEhQKDHRvb2xfY2FsbF9pZBgBIAEoCRIRCgl0b29sX25hbWUYAiABKAkSFgoOYXJndW1lbnRzX2pzb24YAyABKAkiQgoKVG9vbFJlc3VsdBIUCgx0b29sX2NhbGxfaWQYASABKAkSEAoIaXNfZXJyb3IYAiABKAgSDAoEdGV4dBgDIAEoCSJDCgxUb29sUHJvZ3Jlc3MSFAoMdG9vbF9jYWxsX2lkGAEgASgJEg8KB3R1cm5faWQYAiABKAkSDAoEdGV4dBgDIAEoCSIhCg5Xb3JraW5nQ2hhbmdlZBIPCgd3b3JraW5nGAEgASgIIjQKCkNvbXBhY3Rpb24SDwoHc3VtbWFyeRgBIAEoCRIVCg10b2tlbnNfYmVmb3JlGAIgASgEKrIBCg1TZXNzaW9uT3JpZ2luEh4KGlNFU1NJT05fT1JJR0lOX1VOU1BFQ0lGSUVEEAASGgoWU0VTU0lPTl9PUklHSU5fU1RBUlRVUBABEhYKElNFU1NJT05fT1JJR0lOX05FVxACEhkKFVNFU1NJT05fT1JJR0lOX1JFU1VNRRADEhcKE1NFU1NJT05fT1JJR0lOX0ZPUksQBBIZChVTRVNTSU9OX09SSUdJTl9SRUxPQUQQBSrhAQoNVGhpbmtpbmdMZXZlbBIeChpUSElOS0lOR19MRVZFTF9VTlNQRUNJRklFRBAAEhYKElRISU5LSU5HX0xFVkVMX09GRhABEhoKFlRISU5LSU5HX0xFVkVMX01JTklNQUwQAhIWChJUSElOS0lOR19MRVZFTF9MT1cQAxIZChVUSElOS0lOR19MRVZFTF9NRURJVU0QBBIXChNUSElOS0lOR19MRVZFTF9ISUdIEAUSGAoUVEhJTktJTkdfTEVWRUxfWEhJR0gQBhIWChJUSElOS0lOR19MRVZFTF9NQVgQByqCAQoNQ29tbWFuZFNvdXJjZRIeChpDT01NQU5EX1NPVVJDRV9VTlNQRUNJRklFRBAAEhwKGENPTU1BTkRfU09VUkNFX0VYVEVOU0lPThABEhkKFUNPTU1BTkRfU09VUkNFX1BST01QVBACEhgKFENPTU1BTkRfU09VUkNFX1NLSUxMEAMqUAoIRGVsaXZlcnkSGAoUREVMSVZFUllfVU5TUEVDSUZJRUQQABISCg5ERUxJVkVSWV9TVEVFUhABEhYKEkRFTElWRVJZX0ZPTExPV19VUBACKrsBCgpTdG9wUmVhc29uEhsKF1NUT1BfUkVBU09OX1VOU1BFQ0lGSUVEEAASFAoQU1RPUF9SRUFTT05fU1RPUBABEhYKElNUT1BfUkVBU09OX0xFTkdUSBACEhgKFFNUT1BfUkVBU09OX1RPT0xfVVNFEAMSFwoTU1RPUF9SRUFTT05fQUJPUlRFRBAEEhUKEVNUT1BfUkVBU09OX0VSUk9SEAUSGAoUU1RPUF9SRUFTT05fREVGRVJSRUQQBkKtAQoRY29tLnBpcmMudjFhbHBoYTFCDFNlc3Npb25Qcm90b1ABWjVwaXJjLmRldi9yZWxheS9pbnRlcm5hbC9wYi9waXJjL3YxYWxwaGExO3BpcmN2MWFscGhhMaICA1BYWKoCDVBpcmMuVjFhbHBoYTHKAg1QaXJjXFYxYWxwaGEx4gIZUGlyY1xWMWFscGhhMVxHUEJNZXRhZGF0YeoCDlBpcmM6OlYxYWxwaGExYgZwcm90bzM", [file_google_protobuf_timestamp, file_pirc_v1alpha1_common]); var SessionAnnouncementSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 0); -var ModelSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 1); -var SessionMessageSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 2); -var ModelInfoSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 5); -var ImageSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 17); -var HistorySchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 20); -var ConversationItemSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 23); -var ContentBlockSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 26); -var UsageSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 27); +var PlaceSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 1); +var ModelSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 2); +var SessionMessageSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 3); +var ModelInfoSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 6); +var ImageSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 18); +var HistorySchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 21); +var ConversationItemSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 24); +var ContentBlockSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 27); +var UsageSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 28); // relay-client/keys.ts import { createPrivateKey, createPublicKey, generateKeyPairSync, randomBytes, sign } from "node:crypto"; @@ -7184,8 +7185,8 @@ function loadOrCreateKey(path) { } return fromPem(pem); } -function signWith(key, data) { - return new Uint8Array(sign(null, data, key.privateKey)); +function signWith(key2, data) { + return new Uint8Array(sign(null, data, key2.privateKey)); } // relay-client/connection.ts @@ -7624,22 +7625,22 @@ function fitItem(item, budget) { size = toBinary(ConversationItemSchema, item).length; } for (let round = 0; size > budget && round < 8; round++) { - const cut = (t) => clip(t, Math.max(64, Math.floor(t.length * budget / size / 2))); + const cut2 = (t) => clip(t, Math.max(64, Math.floor(t.length * budget / size / 2))); switch (b.case) { case "userMessage": - b.value.text = cut(b.value.text); + b.value.text = cut2(b.value.text); break; case "assistantMessage": - for (const c of b.value.content) if (typeof c.body.value === "string") c.body.value = cut(c.body.value); + for (const c of b.value.content) if (typeof c.body.value === "string") c.body.value = cut2(c.body.value); break; case "toolCall": - b.value.argumentsJson = cut(b.value.argumentsJson); + b.value.argumentsJson = cut2(b.value.argumentsJson); break; case "toolResult": - b.value.text = cut(b.value.text); + b.value.text = cut2(b.value.text); break; case "compaction": - b.value.summary = cut(b.value.summary); + b.value.summary = cut2(b.value.summary); break; } size = toBinary(ConversationItemSchema, item).length; @@ -7775,7 +7776,8 @@ var Live = class { replacesSessionId: this.replaces, origin: this.origin, piVersion: this.versions.pi, - extensionVersion: this.versions.extension + extensionVersion: this.versions.extension, + place: this.sink.place() }); } announcementBytes() { @@ -8210,6 +8212,184 @@ function errorReply(requestId, code, message) { return create(SessionMessageSchema, { body: { case: "error", value: { requestId, code, message } } }); } +// extension/src/place.ts +import { execFile } from "node:child_process"; +import { createConnection } from "node:net"; +var DETECT_MS = 2e3; +var MAX_NAME = 128; +var PLACE_EVENT = "pirc:place"; +function cut(s) { + if (typeof s !== "string") return ""; + const b = Buffer.from(s.trim(), "utf8"); + if (b.length <= MAX_NAME) return s.trim(); + let end = MAX_NAME; + while (end > 0 && (b[end] & 192) === 128) end--; + return b.subarray(0, end).toString("utf8"); +} +function num(n) { + return typeof n === "number" && Number.isInteger(n) && n >= 0 && n < 2 ** 32 ? n : void 0; +} +function place(p) { + const v = { + kind: cut(p.kind), + group: cut(p.group), + window: cut(p.window), + pane: cut(p.pane), + display: cut(p.display), + groupNumber: num(p.groupNumber), + windowNumber: num(p.windowNumber) + }; + if (!v.group && !v.window && !v.pane && !v.display) return void 0; + return create(PlaceSchema, v); +} +function parseGiven(data) { + if (data === null) return null; + if (typeof data !== "object" || Array.isArray(data)) throw new Error("pirc:place takes an object, or null"); + return place(data); +} +function run(cmd, args, env) { + return new Promise((resolve, reject) => { + execFile(cmd, args, { env, timeout: DETECT_MS, encoding: "utf8" }, (err, out) => err ? reject(err) : resolve(out)); + }); +} +async function tmuxPlace(env) { + const pane = env.TMUX_PANE; + if (!env.TMUX || !pane) return void 0; + const out = await run("tmux", ["display-message", "-p", "-t", pane, "#{session_name} #{window_index} #{window_name}"], env); + const [group, windowNumber, window] = out.replace(/\n$/, "").split(" "); + return place({ kind: "tmux", group, window, windowNumber: Number(windowNumber) }); +} +function herdrSession(path) { + const socket = createConnection(path); + let buf = ""; + let n = 0; + const waiting = /* @__PURE__ */ new Map(); + const failAll = (e) => { + for (const w of waiting.values()) w.reject(e); + waiting.clear(); + }; + socket.setEncoding("utf8"); + socket.on("data", (d) => { + buf += d; + let i; + while ((i = buf.indexOf("\n")) >= 0) { + const line = buf.slice(0, i); + buf = buf.slice(i + 1); + let m; + try { + m = JSON.parse(line); + } catch { + continue; + } + const w = m.id ? waiting.get(m.id) : void 0; + if (!w) continue; + waiting.delete(m.id); + if (m.result) w.resolve(m.result); + else w.reject(new Error(`herdr: ${m.error?.message ?? "no result"}`)); + } + }); + socket.on("error", (e) => failAll(e)); + socket.on("close", () => failAll(new Error("herdr closed the connection"))); + return { + ask(method, params) { + const id = `pirc-${++n}`; + return new Promise((resolve, reject) => { + waiting.set(id, { resolve, reject }); + socket.write(`${JSON.stringify({ id, method, params })} +`); + }); + }, + close() { + socket.destroy(); + } + }; +} +async function herdrPlace(env) { + const path = env.HERDR_SOCKET_PATH; + const paneId = env.HERDR_PANE_ID; + if (env.HERDR_ENV !== "1" || !path || !paneId) return void 0; + const h = herdrSession(process.platform === "win32" ? `\\\\.\\pipe\\${path}` : path); + const timer = setTimeout(() => h.close(), DETECT_MS); + try { + const { pane } = await h.ask("pane.current", { caller_pane_id: paneId }); + if (!pane?.workspace_id || !pane.tab_id) return void 0; + const [{ workspace }, { tab }] = await Promise.all([ + h.ask("workspace.get", { workspace_id: pane.workspace_id }), + h.ask("tab.get", { tab_id: pane.tab_id }) + ]); + return place({ + kind: "herdr", + group: workspace?.label, + groupNumber: workspace?.number, + window: tab?.label, + windowNumber: tab?.number, + pane: pane.label + }); + } finally { + clearTimeout(timer); + h.close(); + } +} +async function detectPlace(env = process.env) { + return await herdrPlace(env) ?? await tmuxPlace(env); +} +var PlaceTracker = class { + constructor(onChange, onError, detect = () => detectPlace()) { + this.onChange = onChange; + this.onError = onError; + this.detect = detect; + } + onChange; + onError; + detect; + detected; + // Given by another extension: replaces detection until null hands back. + given; + checking; + again = false; + get current() { + return this.given ? this.given.place : this.detected; + } + // From the pirc:place event. + give(data) { + const before = key(this.current); + const p = parseGiven(data); + this.given = p === null ? void 0 : { place: p }; + if (key(this.current) !== before) this.onChange(); + if (p === null) void this.refresh(); + } + // Checks again; concurrent calls share one check, and a call during one + // runs another after it. + refresh() { + if (this.given) return Promise.resolve(); + if (this.checking) { + this.again = true; + return this.checking; + } + this.checking = (async () => { + do { + this.again = false; + let p; + try { + p = await this.detect(); + } catch (e) { + this.onError(e); + continue; + } + if (this.given) return; + if (key(p) !== key(this.detected)) { + this.detected = p; + this.onChange(); + } + } while (this.again); + })().finally(() => this.checking = void 0); + return this.checking; + } +}; +function key(p) { + return p ? JSON.stringify([p.kind, p.group, p.groupNumber, p.window, p.windowNumber, p.pane, p.display]) : ""; +} + // extension/src/host.ts var CHANGES = /* @__PURE__ */ new Set(["prompt", "abort", "setModel", "setThinkingLevel", "compact", "newSession", "rename"]); var IDEMPOTENCY_ENTRIES = 1e3; @@ -8242,6 +8422,12 @@ var Host = class { // Where each session's sequence numbers left off, for a return to it. seqs = /* @__PURE__ */ new Map(); lastError = ""; + // Where the process runs, announced with its session; checked again on + // activity (bind, a turn, a reconnect, a client's request). + places = new PlaceTracker( + () => this.live?.onAnnouncementChanged(), + (e) => this.fail("place", e) + ); // The live session that `pi` belongs to, if it is still current. liveFor(pi) { return this.live?.pi === pi ? this.live : void 0; @@ -8273,6 +8459,7 @@ var Host = class { } this.suspended = void 0; this.log(`session ${id} (${ev.reason})`); + void this.places.refresh(); if (!this.conn) this.connect(); else if (this.state.kind === "ready") this.announce(this.live); this.showStatus(); @@ -8340,6 +8527,7 @@ var Host = class { if (s.kind === "ready") { if (this.live) this.announce(this.live); if (this.suspended) this.announce(this.suspended); + void this.places.refresh(); } this.showStatus(); } @@ -8404,6 +8592,9 @@ var Host = class { this.fail("announce", e); } } + place() { + return this.places.current; + } maxPayloadBytes() { return this.state.kind === "ready" ? this.state.maxFrameBytes - 512 : 1 << 20; } @@ -8451,6 +8642,7 @@ var Host = class { } this.reply(live, clientKey, reply); }; + void this.places.refresh(); try { live.onRequest(clientKey, m, respond); } catch (e) { @@ -8458,9 +8650,9 @@ var Host = class { respond(errorReply(requestIdOf(m), 13 /* PI_FAILED */, e?.message ?? String(e))); } } - remember(key, v) { - this.replies.delete(key); - this.replies.set(key, v); + remember(key2, v) { + this.replies.delete(key2); + this.replies.set(key2, v); if (this.replies.size > IDEMPOTENCY_ENTRIES) this.replies.delete(this.replies.keys().next().value); } }; @@ -8470,7 +8662,7 @@ function requestIdOf(m) { } // extension/src/index.ts -var EXTENSION_VERSION = true ? "0.1.3" : "dev"; +var EXTENSION_VERSION = true ? "0.1.8" : "dev"; function piVersion() { try { let dir = dirname3(realpathSync(process.argv[1])); @@ -8524,8 +8716,22 @@ function index_default(pi) { pi.on("message_end", on("message_end", (live, e) => live.onMessageEnd(e.message))); pi.on("tool_execution_update", on("tool_execution_update", (live, e) => live.onToolUpdate(e))); pi.on("tool_execution_end", on("tool_execution_end", (live, e) => live.onToolEnd(e.toolCallId))); - pi.on("agent_start", on("agent_start", (live) => live.onWorking(true))); - pi.on("agent_settled", on("agent_settled", (live) => live.onWorking(false))); + pi.on("agent_start", on("agent_start", (live) => { + live.onWorking(true); + void host.places.refresh(); + })); + pi.on("agent_settled", on("agent_settled", (live) => { + live.onWorking(false); + void host.places.refresh(); + })); + proc.stopPlace?.(); + proc.stopPlace = pi.events.on(PLACE_EVENT, (data) => { + try { + host.places.give(data); + } catch (err) { + host.fail(PLACE_EVENT, err); + } + }); pi.on("session_info_changed", on("session_info_changed", (live) => live.onAnnouncementChanged())); pi.on("model_select", on("model_select", (live) => live.onAnnouncementChanged())); pi.on("thinking_level_select", on("thinking_level_select", (live) => live.onAnnouncementChanged())); diff --git a/package.json b/package.json index 741564f..061e1b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pirc-extension", - "version": "0.1.3", + "version": "0.1.8", "description": "PiRC: puts every interactive pi session on a PiRC relay", "license": "MIT", "homepage": "https://pirc.dev", -- cgit v1.2.3