aboutsummaryrefslogtreecommitdiff
path: root/pirc.js
diff options
context:
space:
mode:
authorIgor Soarez <igor@soarez.org>2026-10-28 10:05:45 +0000
committerIgor Soarez <igor@soarez.org>2026-10-28 10:05:45 +0000
commita130fd7689e86c5420a139f334e34fbe605c4441 (patch)
treeda5ac5a846d3062990d2b61dc1603754fc443442 /pirc.js
parent6daa4893f73cd25496e42433a64f0a5b21ef2aed (diff)
pirc-extension 0.1.9-dev+1d13db331154
Diffstat (limited to 'pirc.js')
-rw-r--r--pirc.js376
1 files changed, 188 insertions, 188 deletions
diff --git a/pirc.js b/pirc.js
index 3e0e550..627b0ee 100644
--- a/pirc.js
+++ b/pirc.js
@@ -1,4 +1,4 @@
-// PiRC extension 0.1.9-dev+05e39e0be370. Third-party code in this file: @bufbuild/protobuf@2.16.0, ws@8.22.0; see NOTICE.
+// PiRC extension 0.1.9-dev+1d13db331154. 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;
@@ -7152,6 +7152,37 @@ var ConversationItemSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_sess
var ContentBlockSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 34);
var UsageSchema = /* @__PURE__ */ messageDesc(file_pirc_v1alpha1_session, 35);
+// protocol/helpers.ts
+function errorReply(requestId, code, message) {
+ return create(SessionMessageSchema, { body: { case: "error", value: { requestId, code, message } } });
+}
+function accepted(requestId) {
+ return create(SessionMessageSchema, { body: { case: "accepted", value: { requestId } } });
+}
+function requestIdOf(body) {
+ return body?.value?.requestId ?? "";
+}
+var hex = (b) => Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
+function sameBytes(a, b) {
+ return a.length === b.length && a.every((x, i) => x === b[i]);
+}
+var THINKING_NAMES = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
+var LEVEL = {
+ off: 1 /* OFF */,
+ minimal: 2 /* MINIMAL */,
+ low: 3 /* LOW */,
+ medium: 4 /* MEDIUM */,
+ high: 5 /* HIGH */,
+ xhigh: 6 /* XHIGH */,
+ max: 7 /* MAX */
+};
+function thinkingLevel(name) {
+ return name !== void 0 && Object.hasOwn(LEVEL, name) ? LEVEL[name] : void 0;
+}
+function thinkingName(level) {
+ return THINKING_NAMES.find((n) => LEVEL[n] === level);
+}
+
// relay-client/keys.ts
import { createPrivateKey, createPublicKey, generateKeyPairSync, randomBytes, sign } from "node:crypto";
import { linkSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
@@ -7460,21 +7491,6 @@ function clip(s, max = MAX_TEXT) {
return s.length <= max ? s : s.slice(0, max) + `
[\u2026 ${s.length - max} more characters not sent]`;
}
-var THINKING = {
- off: 1 /* OFF */,
- minimal: 2 /* MINIMAL */,
- low: 3 /* LOW */,
- medium: 4 /* MEDIUM */,
- high: 5 /* HIGH */,
- xhigh: 6 /* XHIGH */,
- max: 7 /* MAX */
-};
-function thinkingLevel(level) {
- return level && THINKING[level] || 0 /* UNSPECIFIED */;
-}
-function thinkingLevelName(level) {
- return Object.keys(THINKING).find((k) => THINKING[k] === level);
-}
function modelRef(m) {
return create(ModelSchema, { provider: m.provider, id: m.id, name: m.name ?? "" });
}
@@ -7600,16 +7616,19 @@ function historyItems(branch) {
if (e.message.role === "user") turnId = e.id;
items.push(...messageItems(e.message, { entryId: e.id, turnId, at: atIso(e.timestamp) }));
} else if (e.type === "compaction") {
- items.push(create(ConversationItemSchema, {
- entryId: e.id,
- turnId,
- at: atIso(e.timestamp),
- body: { case: "compaction", value: { summary: clip(e.summary), tokensBefore: count(e.tokensBefore) } }
- }));
+ items.push(compactionItem(e, turnId));
}
}
return items;
}
+function compactionItem(e, turnId) {
+ return create(ConversationItemSchema, {
+ entryId: e.id,
+ turnId,
+ at: atIso(e.timestamp),
+ body: { case: "compaction", value: { summary: clip(e.summary), tokensBefore: count(e.tokensBefore) } }
+ });
+}
function lastTurnId(branch) {
for (let i = branch.length - 1; i >= 0; i--) {
const e = branch[i];
@@ -7681,11 +7700,52 @@ var PROMPT_ECHO_MS = 10 * 6e4;
var CONFIRM_MS = 3e4;
var PERSIST_MS = 2e3;
var SHOWN = /* @__PURE__ */ new Set(["user", "assistant", "toolResult"]);
-var NEW_SESSION_COMMAND = "pirc:new";
-var FORK_COMMAND = "pirc:fork";
-var CLONE_COMMAND = "pirc:clone";
-var RESUME_COMMAND = "pirc:resume";
-var RELOAD_COMMAND = "pirc:reload";
+var cancelled = (what) => (r) => r.cancelled ? `another extension cancelled the ${what}` : void 0;
+var SESSION_COMMANDS = {
+ new: {
+ name: "pirc:new",
+ description: "PiRC: start a new session (used by PiRC's clients)",
+ reason: "new",
+ timeout: "pi did not start a new session",
+ run: async (_args, ctx) => cancelled("new session")(await ctx.newSession())
+ },
+ // Before a user message, its entry ID the argument.
+ fork: {
+ name: "pirc:fork",
+ description: "PiRC: fork before a user message (used by PiRC's clients)",
+ reason: "fork",
+ timeout: "pi did not fork the session",
+ run: async (id, ctx) => forkProblem(ctx, id, "before") ?? cancelled("fork")(await ctx.fork(id))
+ },
+ clone: {
+ name: "pirc:clone",
+ description: "PiRC: clone the session as it is (used by PiRC's clients)",
+ reason: "fork",
+ timeout: "pi did not clone the session",
+ run: async (_args, ctx) => {
+ const leaf = ctx.sessionManager.getLeafId() ?? "";
+ return forkProblem(ctx, leaf, "at") ?? cancelled("clone")(await ctx.fork(leaf, { position: "at" }));
+ }
+ },
+ // A saved session, its file the argument.
+ resume: {
+ name: "pirc:resume",
+ description: "PiRC: resume a saved session (used by PiRC's clients)",
+ reason: "resume",
+ timeout: "pi did not resume the session",
+ run: async (path, ctx) => await resumeProblem(ctx, path) ?? cancelled("resume")(await ctx.switchSession(path))
+ },
+ reload: {
+ name: "pirc:reload",
+ description: "PiRC: reload pi's resources (used by PiRC's clients)",
+ reason: "reload",
+ timeout: "pi did not reload",
+ run: async (_args, ctx) => {
+ await ctx.reload();
+ return void 0;
+ }
+ }
+};
function forkProblem(ctx, id, position) {
const sm = ctx.sessionManager;
const e = id ? sm.getEntry(id) : void 0;
@@ -7751,8 +7811,12 @@ var ACTION_FOR = {
compact: "compact",
session: "stats"
};
+function commandName(text) {
+ return text.startsWith("/") ? text.slice(1).split(/\s/, 1)[0] : void 0;
+}
+var isPircCommand = (name) => name === "pirc" || name.startsWith("pirc:");
function refusedCommand(name) {
- if (name === "pirc" || name.startsWith("pirc:")) return `/${name} is PiRC's own command; it runs only in pi's terminal`;
+ if (isPircCommand(name)) return `/${name} is PiRC's own command; it runs only in pi's terminal`;
if (!BUILTIN_COMMANDS.has(name)) return void 0;
const action = ACTION_FOR[name];
return `pi's /${name} runs only in its terminal` + (action ? `; use the ${action} action` : "");
@@ -7828,7 +7892,7 @@ var Live = class {
cwd: this.ctx.cwd,
hostname: hostname2(),
model: model && modelRef(model),
- thinkingLevel: thinkingLevel(this.pi.getThinkingLevel()),
+ thinkingLevel: thinkingLevel(this.pi.getThinkingLevel()) ?? 0 /* UNSPECIFIED */,
working: this.working,
compacting: this.compacting,
startedAt: started ? atIso(started) : void 0,
@@ -8046,12 +8110,7 @@ var Live = class {
}
onCompact(entry) {
this.catchUp();
- this.emitItem(create(ConversationItemSchema, {
- entryId: entry.id,
- turnId: this.turnId,
- at: atIso(entry.timestamp),
- body: { case: "compaction", value: { summary: clip(entry.summary), tokensBefore: count(entry.tokensBefore) } }
- }));
+ this.emitItem(compactionItem(entry, this.turnId));
this.onCompactEnd();
}
// --- Requests from clients ------------------------------------------
@@ -8088,8 +8147,8 @@ var Live = class {
// Whether text runs an extension command, which pi handles at once, even
// mid-run, and which starts no run.
isCommand(text) {
- if (!text.startsWith("/")) return false;
- const name = text.slice(1).split(/\s/, 1)[0];
+ const name = commandName(text);
+ if (name === void 0) return false;
return this.pi.getCommands().some((c) => c.source === "extension" && c.name === name);
}
// Why compacting or replacing the session cannot start now, if so.
@@ -8100,9 +8159,22 @@ var Live = class {
if (this.working || !this.ctx.isIdle()) return "the agent is working; stop it first";
return void 0;
}
+ // Runs then with what a promise of pi's gives, unless the session has
+ // ended by then; a rejection is answered PI_FAILED.
+ whenSettled(requestId, where, p, respond, then) {
+ p.then(
+ (v) => {
+ if (this.disposed) return respond(errorReply(requestId, 7 /* SESSION_GONE */, "the session ended"));
+ this.guard(where, () => then(v))();
+ },
+ (e) => respond(errorReply(requestId, 13 /* PI_FAILED */, errorText(e)))
+ );
+ }
// Replaces the session through one of PiRC's commands, answered when pi
- // shuts this session down for `reason` (onShutdown).
- replace(requestId, reason, command, timeout, respond) {
+ // shuts this session down for its reason (onShutdown).
+ replace(requestId, which, args, respond) {
+ const { name, reason, timeout } = SESSION_COMMANDS[which];
+ const command = args ? `/${name} ${args}` : `/${name}`;
const why = this.busy();
if (why) return respond(errorReply(requestId, 8 /* BUSY */, why));
const timer = setTimeout(this.guard("replacement", () => {
@@ -8114,17 +8186,18 @@ var Live = class {
try {
this.pi.sendUserMessage(command, { deliverAs: "followUp", expandPromptTemplates: true });
} catch (e) {
- this.onReplaceFailed(e?.message ?? String(e));
+ this.onReplaceFailed(errorText(e));
}
}
// Handles one request, answering it through respond, now or later.
- onRequest(clientKey, m, respond) {
+ onRequest(m, respond) {
const body = m.body;
switch (body.case) {
case "prompt": {
const { requestId, text, images, delivery } = body.value;
if (!text && images.length === 0) return respond(errorReply(requestId, 4 /* INVALID */, "empty prompt"));
- const refused = text.startsWith("/") ? refusedCommand(text.slice(1).split(/\s/, 1)[0]) : void 0;
+ const name = commandName(text);
+ const refused = name === void 0 ? void 0 : refusedCommand(name);
if (refused) return respond(errorReply(requestId, 4 /* INVALID */, refused));
const command = images.length === 0 && this.isCommand(text);
if (!command && this.compacting) {
@@ -8169,23 +8242,15 @@ var Live = class {
if (!model?.provider || !model.id) return respond(errorReply(requestId, 4 /* INVALID */, "no model given"));
const found = this.ctx.modelRegistry.find(model.provider, model.id);
if (!found) return respond(errorReply(requestId, 4 /* INVALID */, `pi has no model ${model.provider}/${model.id}`));
- const fail = (why) => respond(errorReply(requestId, 13 /* PI_FAILED */, why));
- this.pi.setModel(found).then(
- (ok) => {
- if (this.disposed) return respond(errorReply(requestId, 7 /* SESSION_GONE */, "the session ended"));
- if (!ok) return fail(`pi has no credentials for ${model.provider}`);
- this.guard("set model", () => {
- this.onAnnouncementChanged();
- respond(accepted(requestId));
- })();
- },
- (e) => fail(e?.message ?? String(e))
- );
- return;
+ return this.whenSettled(requestId, "set model", this.pi.setModel(found), respond, (ok) => {
+ if (!ok) return respond(errorReply(requestId, 13 /* PI_FAILED */, `pi has no credentials for ${model.provider}`));
+ this.onAnnouncementChanged();
+ respond(accepted(requestId));
+ });
}
case "setThinkingLevel": {
const { requestId, level } = body.value;
- const name = thinkingLevelName(level);
+ const name = thinkingName(level);
if (!name) return respond(errorReply(requestId, 4 /* INVALID */, "no thinking level given"));
this.pi.setThinkingLevel(name);
this.onAnnouncementChanged();
@@ -8221,46 +8286,34 @@ var Live = class {
return;
}
case "newSession":
- return this.replace(body.value.requestId, "new", `/${NEW_SESSION_COMMAND}`, "pi did not start a new session", respond);
+ return this.replace(body.value.requestId, "new", "", respond);
case "fork": {
const { requestId, entryId } = body.value;
const problem = forkProblem(this.ctx, entryId, "before");
if (problem) return respond(errorReply(requestId, 4 /* INVALID */, problem));
- return this.replace(requestId, "fork", `/${FORK_COMMAND} ${entryId}`, "pi did not fork the session", respond);
+ return this.replace(requestId, "fork", entryId, respond);
}
case "clone": {
const { requestId } = body.value;
const problem = forkProblem(this.ctx, this.ctx.sessionManager.getLeafId() ?? "", "at");
if (problem) return respond(errorReply(requestId, 4 /* INVALID */, problem));
- return this.replace(requestId, "fork", `/${CLONE_COMMAND}`, "pi did not clone the session", respond);
+ return this.replace(requestId, "clone", "", respond);
}
case "listPastSessions": {
const { requestId, allFolders } = body.value;
- pastSessions(this.ctx, allFolders).then(
- (all) => {
- if (this.disposed) return respond(errorReply(requestId, 7 /* SESSION_GONE */, "the session ended"));
- this.guard("past sessions", () => respond(this.pastSessions(requestId, all)))();
- },
- (e) => respond(errorReply(requestId, 13 /* PI_FAILED */, e?.message ?? String(e)))
- );
- return;
+ return this.whenSettled(requestId, "past sessions", pastSessions(this.ctx, allFolders), respond, (all) => respond(this.pastSessions(requestId, all)));
}
case "resume": {
const { requestId, path } = body.value;
const why = this.busy();
if (why) return respond(errorReply(requestId, 8 /* BUSY */, why));
- resumeProblem(this.ctx, path).then(
- (problem) => {
- if (this.disposed) return respond(errorReply(requestId, 7 /* SESSION_GONE */, "the session ended"));
- if (problem) return respond(errorReply(requestId, 4 /* INVALID */, problem));
- this.guard("resume", () => this.replace(requestId, "resume", `/${RESUME_COMMAND} ${path}`, "pi did not resume the session", respond))();
- },
- (e) => respond(errorReply(requestId, 13 /* PI_FAILED */, e?.message ?? String(e)))
- );
- return;
+ return this.whenSettled(requestId, "resume", resumeProblem(this.ctx, path), respond, (problem) => {
+ if (problem) return respond(errorReply(requestId, 4 /* INVALID */, problem));
+ this.replace(requestId, "resume", path, respond);
+ });
}
case "reload":
- return this.replace(body.value.requestId, "reload", `/${RELOAD_COMMAND}`, "pi did not reload", respond);
+ return this.replace(body.value.requestId, "reload", "", respond);
case "statsRequest": {
const usage = this.ctx.getContextUsage();
return respond(create(SessionMessageSchema, {
@@ -8281,7 +8334,7 @@ var Live = class {
case: "commands",
value: {
requestId: body.value.requestId,
- commands: this.pi.getCommands().filter((c) => c.name !== "pirc" && !c.name.startsWith("pirc:")).map((c) => ({ name: c.name, description: c.description ?? "", source: SOURCE[c.source] ?? 0 /* UNSPECIFIED */ }))
+ commands: this.pi.getCommands().filter((c) => !isPircCommand(c.name)).map((c) => ({ name: c.name, description: c.description ?? "", source: SOURCE[c.source] ?? 0 /* UNSPECIFIED */ }))
}
}
}));
@@ -8303,16 +8356,9 @@ var Live = class {
modifiedAt: timestampFromDate(s.modified),
messageCount: s.messageCount
}));
- let sessions = shown;
- const reply = () => create(SessionMessageSchema, {
- body: { case: "pastSessions", value: { requestId, sessions, truncated: sessions.length < shown.length } }
- });
- let m = reply();
- while (sessions.length > 0 && toBinary(SessionMessageSchema, m).length > budget) {
- sessions = sessions.slice(0, sessions.length - Math.max(1, Math.floor(sessions.length / 8)));
- m = reply();
- }
- return m;
+ return fitting(shown.slice().reverse(), budget, (kept) => create(SessionMessageSchema, {
+ body: { case: "pastSessions", value: { requestId, sessions: kept.slice().reverse(), truncated: kept.length < shown.length } }
+ }));
}
// The conversation on the current branch, newest last, within one frame.
history(requestId, limit) {
@@ -8320,28 +8366,26 @@ var Live = class {
this.resolvePending();
const budget = this.sink.maxPayloadBytes() - 1024;
const all = historyItems(this.ctx.sessionManager.getBranch()).map((i) => fitItem(i, budget - 256));
- let items = limit > 0 ? all.slice(-limit) : all;
- let truncated = items.length < all.length;
- const reply = (its) => create(SessionMessageSchema, { body: { case: "history", value: create(HistorySchema, { requestId, items: its, seq: this.seq, truncated }) } });
- let m = reply(items);
- while (items.length > 0 && toBinary(SessionMessageSchema, m).length > budget) {
- items = items.slice(Math.max(1, Math.floor(items.length / 8)));
- truncated = true;
- m = reply(items);
- }
- return m;
+ const items = limit > 0 ? all.slice(-limit) : all;
+ return fitting(items, budget, (kept) => create(SessionMessageSchema, { body: { case: "history", value: create(HistorySchema, { requestId, items: kept, seq: this.seq, truncated: kept.length < all.length }) } }));
}
};
-function accepted(requestId) {
- return create(SessionMessageSchema, { body: { case: "accepted", value: { requestId } } });
+function fitting(items, budget, build) {
+ let kept = items;
+ let m = build(kept);
+ while (kept.length > 0 && toBinary(SessionMessageSchema, m).length > budget) {
+ kept = kept.slice(Math.max(1, Math.floor(kept.length / 8)));
+ m = build(kept);
+ }
+ return m;
+}
+function errorText(e) {
+ return e?.message ?? String(e);
}
function withRequestId(m, requestId) {
if (m.body.case === "accepted" || m.body.case === "error") m.body.value.requestId = requestId;
return m;
}
-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";
@@ -8350,12 +8394,7 @@ 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");
+ return typeof s === "string" ? cutUtf8(s.trim(), MAX_NAME) : "";
}
function num(n) {
return typeof n === "number" && Number.isInteger(n) && n >= 0 && n < 2 ** 32 ? n : void 0;
@@ -8522,15 +8561,27 @@ function key(p) {
}
// extension/src/host.ts
-var CHANGES = /* @__PURE__ */ new Set(["prompt", "abort", "setModel", "setThinkingLevel", "compact", "newSession", "fork", "clone", "resume", "reload", "rename"]);
+var REQUESTS = {
+ prompt: "change",
+ abort: "change",
+ setModel: "change",
+ setThinkingLevel: "change",
+ compact: "change",
+ newSession: "change",
+ fork: "change",
+ clone: "change",
+ resume: "change",
+ reload: "change",
+ rename: "change",
+ historyRequest: "question",
+ listModels: "question",
+ statsRequest: "question",
+ listCommands: "question",
+ listPastSessions: "question"
+};
+var isChange = (c) => c !== void 0 && Object.hasOwn(REQUESTS, c) && REQUESTS[c] === "change";
var IDEMPOTENCY_ENTRIES = 1e3;
var RETRYABLE = /* @__PURE__ */ new Set([8 /* BUSY */, 9 /* TIMEOUT */, 13 /* PI_FAILED */, 4 /* INVALID */, 7 /* SESSION_GONE */]);
-function hex(b) {
- return Buffer.from(b).toString("hex");
-}
-function sameKey(a, b) {
- return a.length === b.length && a.every((x, i) => x === b[i]);
-}
var HANDOVER_MS = 3e4;
var HANDOVER_AFTER_ANNOUNCE_MS = 2e3;
var Host = class _Host {
@@ -8804,18 +8855,18 @@ var Host = class _Host {
if (session) this.routed(session, clientKey, errorReply("", 4 /* INVALID */, "undecodable message"));
return;
}
- if (!session || !this.key || !sameKey(session.hostKey, this.key.publicKey)) return;
+ if (!session || !this.key || !sameBytes(session.hostKey, this.key.publicKey)) return;
const is = (l) => l !== void 0 && session.sessionId === l.sessionId && session.instanceId === l.instanceId;
if (is(this.suspended)) {
- this.routed(session, clientKey, errorReply(requestIdOf(m), 8 /* BUSY */, "pi is reloading; try again shortly"));
+ this.routed(session, clientKey, errorReply(requestIdOf(m.body), 8 /* BUSY */, "pi is reloading; try again shortly"));
return;
}
const live = this.live;
if (!is(live)) {
- this.routed(session, clientKey, errorReply(requestIdOf(m), 7 /* SESSION_GONE */, "session is no longer live in this process"));
+ this.routed(session, clientKey, errorReply(requestIdOf(m.body), 7 /* SESSION_GONE */, "session is no longer live in this process"));
return;
}
- const idem = m.body.case && CHANGES.has(m.body.case) ? `${live.sessionId}/${hex(clientKey)}/${requestIdOf(m)}` : void 0;
+ const idem = isChange(m.body.case) ? `${live.sessionId}/${hex(clientKey)}/${requestIdOf(m.body)}` : void 0;
const seen = idem && this.replies.get(idem);
if (seen === "pending") return;
if (seen) return this.reply(live, clientKey, seen);
@@ -8833,10 +8884,10 @@ var Host = class _Host {
};
void this.places.refresh();
try {
- live.onRequest(clientKey, m, respond);
+ live.onRequest(m, respond);
} catch (e) {
this.fail("request", e);
- respond(errorReply(requestIdOf(m), 13 /* PI_FAILED */, e?.message ?? String(e)));
+ respond(errorReply(requestIdOf(m.body), 13 /* PI_FAILED */, errorText(e)));
}
}
remember(key2, v) {
@@ -8845,13 +8896,9 @@ var Host = class _Host {
if (this.replies.size > IDEMPOTENCY_ENTRIES) this.replies.delete(this.replies.keys().next().value);
}
};
-function requestIdOf(m) {
- const v = m.body.value;
- return v?.requestId ?? "";
-}
// extension/src/index.ts
-var EXTENSION_VERSION = true ? "0.1.9-dev+05e39e0be370" : "dev";
+var EXTENSION_VERSION = true ? "0.1.9-dev+1d13db331154" : "dev";
function piVersion() {
try {
let dir = dirname3(realpathSync(process.argv[1]));
@@ -8866,7 +8913,7 @@ function piVersion() {
}
return "unknown";
}
-var LOAD = true ? "0.1.9-dev+05e39e0be370" : `dev ${randomBytes3(4).toString("hex")}`;
+var LOAD = true ? "0.1.9-dev+1d13db331154" : `dev ${randomBytes3(4).toString("hex")}`;
var KEY = /* @__PURE__ */ Symbol.for("pirc.extension");
var proc = globalThis[KEY] ??= {};
if (!proc.host || proc.load !== LOAD) {
@@ -8929,67 +8976,20 @@ function index_default(pi) {
pi.on("session_before_compact", on("session_before_compact", (live) => live.onCompactStart()));
pi.on("session_compact", on("session_compact", (live, e) => live.onCompact(e.compactionEntry)));
pi.on("session_compact_failed", on("session_compact_failed", (live) => live.onCompactEnd()));
- pi.registerCommand(NEW_SESSION_COMMAND, {
- description: "PiRC: start a new session (used by PiRC's clients)",
- handler: async (_args, ctx) => {
- try {
- const r = await ctx.newSession();
- if (r.cancelled) proc.host.liveFor(pi)?.onReplaceFailed("another extension cancelled the new session");
- } catch (err) {
- proc.host.liveFor(pi)?.onReplaceFailed(err?.message ?? String(err));
- }
- }
- });
- const failed = (why) => proc.host.liveFor(pi)?.onReplaceFailed(why);
- pi.registerCommand(FORK_COMMAND, {
- description: "PiRC: fork before a user message (used by PiRC's clients)",
- handler: async (args, ctx) => {
- const id = args.trim();
- const problem = forkProblem(ctx, id, "before");
- if (problem) return failed(problem);
- try {
- if ((await ctx.fork(id)).cancelled) failed("another extension cancelled the fork");
- } catch (err) {
- failed(err?.message ?? String(err));
- }
- }
- });
- pi.registerCommand(CLONE_COMMAND, {
- description: "PiRC: clone the session as it is (used by PiRC's clients)",
- handler: async (_args, ctx) => {
- const leaf = ctx.sessionManager.getLeafId() ?? "";
- const problem = forkProblem(ctx, leaf, "at");
- if (problem) return failed(problem);
- try {
- if ((await ctx.fork(leaf, { position: "at" })).cancelled) failed("another extension cancelled the clone");
- } catch (err) {
- failed(err?.message ?? String(err));
- }
- }
- });
- pi.registerCommand(RESUME_COMMAND, {
- description: "PiRC: resume a saved session (used by PiRC's clients)",
- handler: async (args, ctx) => {
- const path = args.trim();
- try {
- const problem = await resumeProblem(ctx, path);
- if (problem) return failed(problem);
- if ((await ctx.switchSession(path)).cancelled) failed("another extension cancelled the resume");
- } catch (err) {
- failed(err?.message ?? String(err));
- }
- }
- });
- pi.registerCommand(RELOAD_COMMAND, {
- description: "PiRC: reload pi's resources (used by PiRC's clients)",
- handler: async (_args, ctx) => {
- try {
- await ctx.reload();
- } catch (err) {
- failed(err?.message ?? String(err));
+ for (const c of Object.values(SESSION_COMMANDS)) {
+ pi.registerCommand(c.name, {
+ description: c.description,
+ handler: async (args, ctx) => {
+ let failed;
+ try {
+ failed = await c.run(args.trim(), ctx);
+ } catch (err) {
+ failed = errorText(err);
+ }
+ if (failed) proc.host.liveFor(pi)?.onReplaceFailed(failed);
}
- }
- });
+ });
+ }
pi.registerCommand("pirc", {
description: "PiRC: status, enrol <relay-url> [token], reconnect",
handler: async (args, ctx) => {