@critiquedotsh/harness 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +493 -230
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -7787,8 +7787,8 @@ async function createWorkspaceArchive(args) {
|
|
|
7787
7787
|
if (relativeDestination.startsWith(`..${sep}`) || relativeDestination === ".." || isAbsolute(relativeDestination)) {
|
|
7788
7788
|
throw new ChangeCapsuleError(`Unsafe workspace archive path: ${file.path}`, "invalid_path");
|
|
7789
7789
|
}
|
|
7790
|
-
const { mkdir:
|
|
7791
|
-
await
|
|
7790
|
+
const { mkdir: mkdir18 } = await import("node:fs/promises");
|
|
7791
|
+
await mkdir18(dirname(destination), { recursive: true });
|
|
7792
7792
|
await writeFile(destination, file.content, { mode: 384, flag: "wx" });
|
|
7793
7793
|
}
|
|
7794
7794
|
await execFileAsync("tar", ["-czf", archivePath, "--exclude=.git", "-C", snapshotRoot, "."], {
|
|
@@ -11069,7 +11069,11 @@ var init_pi_session_harness = __esm({
|
|
|
11069
11069
|
void active.kernel.abort();
|
|
11070
11070
|
}, timeoutMs);
|
|
11071
11071
|
try {
|
|
11072
|
-
const turn = await active.kernel.prompt({
|
|
11072
|
+
const turn = await active.kernel.prompt({
|
|
11073
|
+
prompt: input.prompt,
|
|
11074
|
+
signal: controller.signal,
|
|
11075
|
+
...input.images && input.images.length > 0 ? { images: input.images } : {}
|
|
11076
|
+
});
|
|
11073
11077
|
if (timedOut) throw new Error(`Pi session exceeded ${timeoutMs}ms.`);
|
|
11074
11078
|
const serialized = typeof turn.output === "string" ? turn.output : JSON.stringify(turn.output);
|
|
11075
11079
|
if (Buffer.byteLength(serialized) > this.#maxOutputBytes) {
|
|
@@ -13599,7 +13603,10 @@ var init_earendil_pi_driver = __esm({
|
|
|
13599
13603
|
try {
|
|
13600
13604
|
const promptRelease = await this.#egress.release({ kind: "model_prompt", content: input.prompt });
|
|
13601
13605
|
if (promptRelease.content === void 0) throw new Error(`Pi model prompt egress was denied: ${promptRelease.decision.outcome}.`);
|
|
13602
|
-
await this.#session.prompt(
|
|
13606
|
+
await this.#session.prompt(
|
|
13607
|
+
promptRelease.content,
|
|
13608
|
+
input.images && input.images.length > 0 ? { images: input.images.map((image) => ({ type: "image", data: image.data, mimeType: image.mimeType })) } : void 0
|
|
13609
|
+
);
|
|
13603
13610
|
const message = lastAssistantMessage(this.#session);
|
|
13604
13611
|
const rawOutput = this.#assistantText || contentText(message?.content);
|
|
13605
13612
|
const outputRelease = await this.#egress.release({ kind: "model_response", content: rawOutput });
|
|
@@ -13731,11 +13738,11 @@ import { parseArgs } from "node:util";
|
|
|
13731
13738
|
|
|
13732
13739
|
// lib/finish/critique-code-local-author.ts
|
|
13733
13740
|
init_change_capsule();
|
|
13734
|
-
import { createHash as createHash38, randomBytes } from "node:crypto";
|
|
13741
|
+
import { createHash as createHash38, randomBytes as randomBytes2 } from "node:crypto";
|
|
13735
13742
|
import { watch } from "node:fs";
|
|
13736
|
-
import { mkdir as
|
|
13743
|
+
import { mkdir as mkdir15, readFile as readFile23, unlink as unlink4, writeFile as writeFile14 } from "node:fs/promises";
|
|
13737
13744
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
13738
|
-
import { isAbsolute as isAbsolute19, join as
|
|
13745
|
+
import { isAbsolute as isAbsolute19, join as join20 } from "node:path";
|
|
13739
13746
|
import { createInterface } from "node:readline";
|
|
13740
13747
|
|
|
13741
13748
|
// lib/finish/critique-code-author-coordinator.ts
|
|
@@ -20593,6 +20600,90 @@ function formatAuthorReviewStatus(input) {
|
|
|
20593
20600
|
|
|
20594
20601
|
// lib/finish/critique-code-local-author.ts
|
|
20595
20602
|
init_critique_code_kernel();
|
|
20603
|
+
|
|
20604
|
+
// lib/finish/critique-code-web-images.ts
|
|
20605
|
+
import { mkdir as mkdir12, readFile as readFile17, writeFile as writeFile11 } from "node:fs/promises";
|
|
20606
|
+
import { join as join15 } from "node:path";
|
|
20607
|
+
import { randomBytes } from "node:crypto";
|
|
20608
|
+
var MARK_START = "<<<critique-code-images>>>";
|
|
20609
|
+
var MARK_END = "<<<end>>>";
|
|
20610
|
+
var MAX_IMAGES = 8;
|
|
20611
|
+
var MAX_BYTES = 6 * 1024 * 1024;
|
|
20612
|
+
function normalizePromptImageMime(value) {
|
|
20613
|
+
const mime = value.trim().toLowerCase();
|
|
20614
|
+
if (mime === "image/jpg") return "image/jpeg";
|
|
20615
|
+
if (mime === "image/png" || mime === "image/jpeg" || mime === "image/webp" || mime === "image/gif") return mime;
|
|
20616
|
+
return void 0;
|
|
20617
|
+
}
|
|
20618
|
+
function parseWebPromptImages(input) {
|
|
20619
|
+
if (!Array.isArray(input)) return [];
|
|
20620
|
+
const out = [];
|
|
20621
|
+
for (const row of input.slice(0, MAX_IMAGES)) {
|
|
20622
|
+
if (!row || typeof row !== "object") continue;
|
|
20623
|
+
const rec = row;
|
|
20624
|
+
const mime = normalizePromptImageMime(String(rec.mimeType ?? rec.mime ?? rec.type ?? ""));
|
|
20625
|
+
const data = String(rec.data ?? rec.b64 ?? "").replace(/^data:[^;]+;base64,/, "").replace(/\s/g, "");
|
|
20626
|
+
if (!mime || !data) continue;
|
|
20627
|
+
const bytes = Buffer.from(data, "base64");
|
|
20628
|
+
if (bytes.length === 0 || bytes.length > MAX_BYTES) continue;
|
|
20629
|
+
out.push({
|
|
20630
|
+
mimeType: mime,
|
|
20631
|
+
data: bytes.toString("base64"),
|
|
20632
|
+
...typeof rec.name === "string" && rec.name.trim() ? { name: rec.name.trim().slice(0, 80) } : {}
|
|
20633
|
+
});
|
|
20634
|
+
}
|
|
20635
|
+
return out;
|
|
20636
|
+
}
|
|
20637
|
+
function extForMime(mime) {
|
|
20638
|
+
if (mime === "image/jpeg") return "jpg";
|
|
20639
|
+
if (mime === "image/webp") return "webp";
|
|
20640
|
+
if (mime === "image/gif") return "gif";
|
|
20641
|
+
return "png";
|
|
20642
|
+
}
|
|
20643
|
+
async function writeWebPromptImages(input) {
|
|
20644
|
+
if (input.images.length === 0) return [];
|
|
20645
|
+
const dir = join15(input.home, "inbox");
|
|
20646
|
+
await mkdir12(dir, { recursive: true });
|
|
20647
|
+
const paths = [];
|
|
20648
|
+
for (const image of input.images) {
|
|
20649
|
+
const name = `${Date.now()}-${randomBytes(4).toString("hex")}.${extForMime(image.mimeType)}`;
|
|
20650
|
+
const path2 = join15(dir, name);
|
|
20651
|
+
await writeFile11(path2, Buffer.from(image.data, "base64"));
|
|
20652
|
+
paths.push(path2);
|
|
20653
|
+
}
|
|
20654
|
+
return paths;
|
|
20655
|
+
}
|
|
20656
|
+
function wrapPromptWithImagePaths(text, paths) {
|
|
20657
|
+
if (paths.length === 0) return text;
|
|
20658
|
+
return `${MARK_START}
|
|
20659
|
+
${paths.join("\n")}
|
|
20660
|
+
${MARK_END}
|
|
20661
|
+
${text}`;
|
|
20662
|
+
}
|
|
20663
|
+
function unwrapPromptImagePaths(line) {
|
|
20664
|
+
if (!line.startsWith(MARK_START)) return { text: line, paths: [] };
|
|
20665
|
+
const end = line.indexOf(`
|
|
20666
|
+
${MARK_END}
|
|
20667
|
+
`);
|
|
20668
|
+
if (end < 0) return { text: line, paths: [] };
|
|
20669
|
+
const block = line.slice(MARK_START.length + 1, end);
|
|
20670
|
+
const paths = block.split("\n").map((item) => item.trim()).filter(Boolean);
|
|
20671
|
+
const text = line.slice(end + MARK_END.length + 2);
|
|
20672
|
+
return { text, paths };
|
|
20673
|
+
}
|
|
20674
|
+
async function loadPromptImagesFromPaths(paths) {
|
|
20675
|
+
const images = [];
|
|
20676
|
+
for (const path2 of paths.slice(0, MAX_IMAGES)) {
|
|
20677
|
+
const bytes = await readFile17(path2);
|
|
20678
|
+
if (bytes.length === 0 || bytes.length > MAX_BYTES) continue;
|
|
20679
|
+
const lower = path2.toLowerCase();
|
|
20680
|
+
const mime = lower.endsWith(".jpg") || lower.endsWith(".jpeg") ? "image/jpeg" : lower.endsWith(".webp") ? "image/webp" : lower.endsWith(".gif") ? "image/gif" : "image/png";
|
|
20681
|
+
images.push({ mimeType: mime, data: bytes.toString("base64") });
|
|
20682
|
+
}
|
|
20683
|
+
return images;
|
|
20684
|
+
}
|
|
20685
|
+
|
|
20686
|
+
// lib/finish/critique-code-local-author.ts
|
|
20596
20687
|
init_critique_code_model_defaults();
|
|
20597
20688
|
init_critique_code_runtime_config();
|
|
20598
20689
|
|
|
@@ -20861,24 +20952,26 @@ function filterMenuRows(items, query) {
|
|
|
20861
20952
|
}), ...back];
|
|
20862
20953
|
}
|
|
20863
20954
|
|
|
20864
|
-
// lib/finish/critique-code-web-
|
|
20865
|
-
var
|
|
20866
|
-
|
|
20867
|
-
|
|
20868
|
-
deepseek:
|
|
20869
|
-
google:
|
|
20870
|
-
groq:
|
|
20871
|
-
kimi:
|
|
20872
|
-
meta:
|
|
20873
|
-
minimax:
|
|
20874
|
-
mistral:
|
|
20875
|
-
nvidia:
|
|
20876
|
-
openai:
|
|
20877
|
-
qwen:
|
|
20878
|
-
xai:
|
|
20879
|
-
zai:
|
|
20880
|
-
other:
|
|
20955
|
+
// lib/finish/critique-code-web-lobe-svgs.ts
|
|
20956
|
+
var LOBE_MODEL_ICON_SVGS = {
|
|
20957
|
+
critique: '<svg class="model-ico" width="16" height="16" viewBox="0 0 32 32" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><rect width="32" height="32" rx="4" fill="#0d6336"/><path d="M16 5.5 26.5 16 16 26.5 5.5 16 16 5.5Z" stroke="#f7f4ee" stroke-width="1.4" fill="none"/><path d="M20.2 11.2c-1.1-1-2.5-1.5-4.2-1.5-3.4 0-5.6 2.2-5.6 6.3 0 4.1 2.2 6.3 5.6 6.3 1.7 0 3.1-.5 4.2-1.5" stroke="#f7f4ee" stroke-width="1.8" stroke-linecap="square" fill="none"/></svg>',
|
|
20958
|
+
anthropic: '<svg class="model-ico" width="16" height="16" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z" fill="#D97757" fill-rule="nonzero"></path></svg>',
|
|
20959
|
+
deepseek: '<svg class="model-ico" width="16" height="16" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z" fill="#4D6BFE"></path></svg>',
|
|
20960
|
+
google: '<svg class="model-ico" width="16" height="16" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z" fill="#3186FF"></path><path d="M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z" fill="url(#lobe-icons-gemini-0-_R_0_)"></path><path d="M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z" fill="url(#lobe-icons-gemini-1-_R_0_)"></path><path d="M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z" fill="url(#lobe-icons-gemini-2-_R_0_)"></path><defs><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-gemini-0-_R_0_" x1="7" x2="11" y1="15.5" y2="12"><stop stop-color="#08B962"></stop><stop offset="1" stop-color="#08B962" stop-opacity="0"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-gemini-1-_R_0_" x1="8" x2="11.5" y1="5.5" y2="11"><stop stop-color="#F94543"></stop><stop offset="1" stop-color="#F94543" stop-opacity="0"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-gemini-2-_R_0_" x1="3.5" x2="17.5" y1="13.5" y2="12"><stop stop-color="#FABC12"></stop><stop offset=".46" stop-color="#FABC12" stop-opacity="0"></stop></linearGradient></defs></svg>',
|
|
20961
|
+
groq: '<svg class="model-ico" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="24" rx="5" fill="#F55036"/><g transform="translate(3.2 3.2) scale(0.733)"><path d="M12.036 2c-3.853-.035-7 3-7.036 6.781-.035 3.782 3.055 6.872 6.908 6.907h2.42v-2.566h-2.292c-2.407.028-4.38-1.866-4.408-4.23-.029-2.362 1.901-4.298 4.308-4.326h.1c2.407 0 4.358 1.915 4.365 4.278v6.305c0 2.342-1.944 4.25-4.323 4.279a4.375 4.375 0 01-3.033-1.252l-1.851 1.818A7 7 0 0012.029 22h.092c3.803-.056 6.858-3.083 6.879-6.816v-6.5C18.907 4.963 15.817 2 12.036 2z"></path></g></svg>',
|
|
20962
|
+
kimi: '<svg class="model-ico" width="16" height="16" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M21.846 0a1.923 1.923 0 110 3.846H20.15a.226.226 0 01-.227-.226V1.923C19.923.861 20.784 0 21.846 0z" fill="#1783FF"></path><path d="M11.065 11.199l7.257-7.2c.137-.136.06-.41-.116-.41H14.3a.164.164 0 00-.117.051l-7.82 7.756c-.122.12-.302.013-.302-.179V3.82c0-.127-.083-.23-.185-.23H3.186c-.103 0-.186.103-.186.23V19.77c0 .128.083.23.186.23h2.69c.103 0 .186-.102.186-.23v-3.25c0-.069.025-.135.069-.178l2.424-2.406a.158.158 0 01.205-.023l6.484 4.772a7.677 7.677 0 003.453 1.283c.108.012.2-.095.2-.23v-3.06c0-.117-.07-.212-.164-.227a5.028 5.028 0 01-2.027-.807l-5.613-4.064c-.117-.078-.132-.279-.028-.381z" fill="#fff"></path></svg>',
|
|
20963
|
+
meta: '<svg class="model-ico" width="16" height="16" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M6.897 4h-.024l-.031 2.615h.022c1.715 0 3.046 1.357 5.94 6.246l.175.297.012.02 1.62-2.438-.012-.019a48.763 48.763 0 00-1.098-1.716 28.01 28.01 0 00-1.175-1.629C10.413 4.932 8.812 4 6.896 4z" fill="url(#lobe-icons-meta-0-_R_0_)"></path><path d="M6.873 4C4.95 4.01 3.247 5.258 2.02 7.17a4.352 4.352 0 00-.01.017l2.254 1.231.011-.017c.718-1.083 1.61-1.774 2.568-1.785h.021L6.896 4h-.023z" fill="url(#lobe-icons-meta-1-_R_0_)"></path><path d="M2.019 7.17l-.011.017C1.2 8.447.598 9.995.274 11.664l-.005.022 2.534.6.004-.022c.27-1.467.786-2.828 1.456-3.845l.011-.017L2.02 7.17z" fill="url(#lobe-icons-meta-2-_R_0_)"></path><path d="M2.807 12.264l-2.533-.6-.005.022c-.177.918-.267 1.851-.269 2.786v.023l2.598.233v-.023a12.591 12.591 0 01.21-2.44z" fill="url(#lobe-icons-meta-3-_R_0_)"></path><path d="M2.677 15.537a5.462 5.462 0 01-.079-.813v-.022L0 14.468v.024a8.89 8.89 0 00.146 1.652l2.535-.585a4.106 4.106 0 01-.004-.022z" fill="url(#lobe-icons-meta-4-_R_0_)"></path><path d="M3.27 16.89c-.284-.31-.484-.756-.589-1.328l-.004-.021-2.535.585.004.021c.192 1.01.568 1.85 1.106 2.487l.014.017 2.018-1.745a2.106 2.106 0 01-.015-.016z" fill="url(#lobe-icons-meta-5-_R_0_)"></path><path d="M10.78 9.654c-1.528 2.35-2.454 3.825-2.454 3.825-2.035 3.2-2.739 3.917-3.871 3.917a1.545 1.545 0 01-1.186-.508l-2.017 1.744.014.017C2.01 19.518 3.058 20 4.356 20c1.963 0 3.374-.928 5.884-5.33l1.766-3.13a41.283 41.283 0 00-1.227-1.886z" fill="#0082FB"></path><path d="M13.502 5.946l-.016.016c-.4.43-.786.908-1.16 1.416.378.483.768 1.024 1.175 1.63.48-.743.928-1.345 1.367-1.807l.016-.016-1.382-1.24z" fill="url(#lobe-icons-meta-6-_R_0_)"></path><path d="M20.918 5.713C19.853 4.633 18.583 4 17.225 4c-1.432 0-2.637.787-3.723 1.944l-.016.016 1.382 1.24.016-.017c.715-.747 1.408-1.12 2.176-1.12.826 0 1.6.39 2.27 1.075l.015.016 1.589-1.425-.016-.016z" fill="#0082FB"></path><path d="M23.998 14.125c-.06-3.467-1.27-6.566-3.064-8.396l-.016-.016-1.588 1.424.015.016c1.35 1.392 2.277 3.98 2.361 6.971v.023h2.292v-.022z" fill="url(#lobe-icons-meta-7-_R_0_)"></path><path d="M23.998 14.15v-.023h-2.292v.022c.004.14.006.282.006.424 0 .815-.121 1.474-.368 1.95l-.011.022 1.708 1.782.013-.02c.62-.96.946-2.293.946-3.91 0-.083 0-.165-.002-.247z" fill="url(#lobe-icons-meta-8-_R_0_)"></path><path d="M21.344 16.52l-.011.02c-.214.402-.519.67-.917.787l.778 2.462a3.493 3.493 0 00.438-.182 3.558 3.558 0 001.366-1.218l.044-.065.012-.02-1.71-1.784z" fill="url(#lobe-icons-meta-9-_R_0_)"></path><path d="M19.92 17.393c-.262 0-.492-.039-.718-.14l-.798 2.522c.449.153.927.222 1.46.222.492 0 .943-.073 1.352-.215l-.78-2.462c-.167.05-.341.075-.517.073z" fill="url(#lobe-icons-meta-10-_R_0_)"></path><path d="M18.323 16.534l-.014-.017-1.836 1.914.016.017c.637.682 1.246 1.105 1.937 1.337l.797-2.52c-.291-.125-.573-.353-.9-.731z" fill="url(#lobe-icons-meta-11-_R_0_)"></path><path d="M18.309 16.515c-.55-.642-1.232-1.712-2.303-3.44l-1.396-2.336-.011-.02-1.62 2.438.012.02.989 1.668c.959 1.61 1.74 2.774 2.493 3.585l.016.016 1.834-1.914a2.353 2.353 0 01-.014-.017z" fill="url(#lobe-icons-meta-12-_R_0_)"></path><defs><linearGradient id="lobe-icons-meta-0-_R_0_" x1="75.897%" x2="26.312%" y1="89.199%" y2="12.194%"><stop offset=".06%" stop-color="#0867DF"></stop><stop offset="45.39%" stop-color="#0668E1"></stop><stop offset="85.91%" stop-color="#0064E0"></stop></linearGradient><linearGradient id="lobe-icons-meta-1-_R_0_" x1="21.67%" x2="97.068%" y1="75.874%" y2="23.985%"><stop offset="13.23%" stop-color="#0064DF"></stop><stop offset="99.88%" stop-color="#0064E0"></stop></linearGradient><linearGradient id="lobe-icons-meta-2-_R_0_" x1="38.263%" x2="60.895%" y1="89.127%" y2="16.131%"><stop offset="1.47%" stop-color="#0072EC"></stop><stop offset="68.81%" stop-color="#0064DF"></stop></linearGradient><linearGradient id="lobe-icons-meta-3-_R_0_" x1="47.032%" x2="52.15%" y1="90.19%" y2="15.745%"><stop offset="7.31%" stop-color="#007CF6"></stop><stop offset="99.43%" stop-color="#0072EC"></stop></linearGradient><linearGradient id="lobe-icons-meta-4-_R_0_" x1="52.155%" x2="47.591%" y1="58.301%" y2="37.004%"><stop offset="7.31%" stop-color="#007FF9"></stop><stop offset="100%" stop-color="#007CF6"></stop></linearGradient><linearGradient id="lobe-icons-meta-5-_R_0_" x1="37.689%" x2="61.961%" y1="12.502%" y2="63.624%"><stop offset="7.31%" stop-color="#007FF9"></stop><stop offset="100%" stop-color="#0082FB"></stop></linearGradient><linearGradient id="lobe-icons-meta-6-_R_0_" x1="34.808%" x2="62.313%" y1="68.859%" y2="23.174%"><stop offset="27.99%" stop-color="#007FF8"></stop><stop offset="91.41%" stop-color="#0082FB"></stop></linearGradient><linearGradient id="lobe-icons-meta-7-_R_0_" x1="43.762%" x2="57.602%" y1="6.235%" y2="98.514%"><stop offset="0%" stop-color="#0082FB"></stop><stop offset="99.95%" stop-color="#0081FA"></stop></linearGradient><linearGradient id="lobe-icons-meta-8-_R_0_" x1="60.055%" x2="39.88%" y1="4.661%" y2="69.077%"><stop offset="6.19%" stop-color="#0081FA"></stop><stop offset="100%" stop-color="#0080F9"></stop></linearGradient><linearGradient id="lobe-icons-meta-9-_R_0_" x1="30.282%" x2="61.081%" y1="59.32%" y2="33.244%"><stop offset="0%" stop-color="#027AF3"></stop><stop offset="100%" stop-color="#0080F9"></stop></linearGradient><linearGradient id="lobe-icons-meta-10-_R_0_" x1="20.433%" x2="82.112%" y1="50.001%" y2="50.001%"><stop offset="0%" stop-color="#0377EF"></stop><stop offset="99.94%" stop-color="#0279F1"></stop></linearGradient><linearGradient id="lobe-icons-meta-11-_R_0_" x1="40.303%" x2="72.394%" y1="35.298%" y2="57.811%"><stop offset=".19%" stop-color="#0471E9"></stop><stop offset="100%" stop-color="#0377EF"></stop></linearGradient><linearGradient id="lobe-icons-meta-12-_R_0_" x1="32.254%" x2="68.003%" y1="19.719%" y2="84.908%"><stop offset="27.65%" stop-color="#0867DF"></stop><stop offset="100%" stop-color="#0471E9"></stop></linearGradient></defs></svg>',
|
|
20964
|
+
minimax: '<svg class="model-ico" width="16" height="16" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="lobe-icons-minimax-_R_0_" x1="0%" x2="100.182%" y1="50.057%" y2="50.057%"><stop offset="0%" stop-color="#E2167E"></stop><stop offset="100%" stop-color="#FE603C"></stop></linearGradient></defs><path d="M16.278 2c1.156 0 2.093.927 2.093 2.07v12.501a.74.74 0 00.744.709.74.74 0 00.743-.709V9.099a2.06 2.06 0 012.071-2.049A2.06 2.06 0 0124 9.1v6.561a.649.649 0 01-.652.645.649.649 0 01-.653-.645V9.1a.762.762 0 00-.766-.758.762.762 0 00-.766.758v7.472a2.037 2.037 0 01-2.048 2.026 2.037 2.037 0 01-2.048-2.026v-12.5a.785.785 0 00-.788-.753.785.785 0 00-.789.752l-.001 15.904A2.037 2.037 0 0113.441 22a2.037 2.037 0 01-2.048-2.026V18.04c0-.356.292-.645.652-.645.36 0 .652.289.652.645v1.934c0 .263.142.506.372.638.23.131.514.131.744 0a.734.734 0 00.372-.638V4.07c0-1.143.937-2.07 2.093-2.07zm-5.674 0c1.156 0 2.093.927 2.093 2.07v11.523a.648.648 0 01-.652.645.648.648 0 01-.652-.645V4.07a.785.785 0 00-.789-.78.785.785 0 00-.789.78v14.013a2.06 2.06 0 01-2.07 2.048 2.06 2.06 0 01-2.071-2.048V9.1a.762.762 0 00-.766-.758.762.762 0 00-.766.758v3.8a2.06 2.06 0 01-2.071 2.049A2.06 2.06 0 010 12.9v-1.378c0-.357.292-.646.652-.646.36 0 .653.29.653.646V12.9c0 .418.343.757.766.757s.766-.339.766-.757V9.099a2.06 2.06 0 012.07-2.048 2.06 2.06 0 012.071 2.048v8.984c0 .419.343.758.767.758.423 0 .766-.339.766-.758V4.07c0-1.143.937-2.07 2.093-2.07z" fill="url(#lobe-icons-minimax-_R_0_)" fill-rule="nonzero"></path></svg>',
|
|
20965
|
+
mistral: '<svg class="model-ico" width="16" height="16" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M3.428 3.4h3.429v3.428H3.428V3.4zm13.714 0h3.43v3.428h-3.43V3.4z" fill="gold"></path><path d="M3.428 6.828h6.857v3.429H3.429V6.828zm10.286 0h6.857v3.429h-6.857V6.828z" fill="#FFAF00"></path><path d="M3.428 10.258h17.144v3.428H3.428v-3.428z" fill="#FF8205"></path><path d="M3.428 13.686h3.429v3.428H3.428v-3.428zm6.858 0h3.429v3.428h-3.429v-3.428zm6.856 0h3.43v3.428h-3.43v-3.428z" fill="#FA500F"></path><path d="M0 17.114h10.286v3.429H0v-3.429zm13.714 0H24v3.429H13.714v-3.429z" fill="#E10500"></path></svg>',
|
|
20966
|
+
nvidia: '<svg class="model-ico" width="16" height="16" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M10.212 8.976V7.62c.127-.01.256-.017.388-.021 3.596-.117 5.957 3.184 5.957 3.184s-2.548 3.647-5.282 3.647a3.227 3.227 0 01-1.063-.175v-4.109c1.4.174 1.681.812 2.523 2.258l1.873-1.627a4.905 4.905 0 00-3.67-1.846 6.594 6.594 0 00-.729.044m0-4.476v2.025c.13-.01.259-.019.388-.024 5.002-.174 8.261 4.226 8.261 4.226s-3.743 4.69-7.643 4.69c-.338 0-.675-.031-1.007-.092v1.25c.278.038.558.057.838.057 3.629 0 6.253-1.91 8.794-4.169.421.347 2.146 1.193 2.501 1.564-2.416 2.083-8.048 3.763-11.24 3.763-.308 0-.603-.02-.894-.048V19.5H24v-15H10.21zm0 9.756v1.068c-3.356-.616-4.287-4.21-4.287-4.21a7.173 7.173 0 014.287-2.138v1.172h-.005a3.182 3.182 0 00-2.502 1.178s.615 2.276 2.507 2.931m-5.961-3.3c1.436-1.935 3.604-3.148 5.961-3.336V6.523C5.81 6.887 2 10.723 2 10.723s2.158 6.427 8.21 7.015v-1.166C5.77 16 4.25 10.958 4.25 10.958h-.002z" fill="#74B71B" fill-rule="nonzero"></path></svg>',
|
|
20967
|
+
openai: '<svg class="model-ico" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="24" rx="5" fill="#10A37F"/><g transform="translate(3.2 3.2) scale(0.733)"><path d="M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"></path></g></svg>',
|
|
20968
|
+
qwen: '<svg class="model-ico" width="16" height="16" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z" fill="url(#lobe-icons-qwen-_R_0_)" fill-rule="nonzero"></path><defs><linearGradient id="lobe-icons-qwen-_R_0_" x1="0%" x2="100%" y1="0%" y2="0%"><stop offset="0%" stop-color="#6336E7" stop-opacity=".84"></stop><stop offset="100%" stop-color="#6F69F7" stop-opacity=".84"></stop></linearGradient></defs></svg>',
|
|
20969
|
+
xai: '<svg class="model-ico" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="24" rx="5" fill="#111111"/><g transform="translate(3.2 3.2) scale(0.733)"><path d="M9.27 15.29l7.978-5.897c.391-.29.95-.177 1.137.272.98 2.369.542 5.215-1.41 7.169-1.951 1.954-4.667 2.382-7.149 1.406l-2.711 1.257c3.889 2.661 8.611 2.003 11.562-.953 2.341-2.344 3.066-5.539 2.388-8.42l.006.007c-.983-4.232.242-5.924 2.75-9.383.06-.082.12-.164.179-.248l-3.301 3.305v-.01L9.267 15.292M7.623 16.723c-2.792-2.67-2.31-6.801.071-9.184 1.761-1.763 4.647-2.483 7.166-1.425l2.705-1.25a7.808 7.808 0 00-1.829-1A8.975 8.975 0 005.984 5.83c-2.533 2.536-3.33 6.436-1.962 9.764 1.022 2.487-.653 4.246-2.34 6.022-.599.63-1.199 1.259-1.682 1.925l7.62-6.815"></path></g></svg>',
|
|
20970
|
+
zai: '<svg class="model-ico" width="16" height="16" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M11.991 23.503a.24.24 0 00-.244.248.24.24 0 00.244.249.24.24 0 00.245-.249.24.24 0 00-.22-.247l-.025-.001zM9.671 5.365a1.697 1.697 0 011.099 2.132l-.071.172-.016.04-.018.054c-.07.16-.104.32-.104.498-.035.71.47 1.279 1.186 1.314h.366c1.309.053 2.338 1.173 2.286 2.523-.052 1.332-1.152 2.38-2.478 2.327h-.174c-.715.018-1.274.64-1.239 1.368 0 .124.018.23.053.337.209.373.54.658.96.8.75.23 1.517-.125 1.9-.782l.018-.035c.402-.64 1.17-.96 1.92-.711.854.284 1.378 1.226 1.099 2.167a1.661 1.661 0 01-2.077 1.102 1.711 1.711 0 01-.907-.711l-.017-.035c-.2-.323-.463-.58-.851-.711l-.056-.018a1.646 1.646 0 00-1.954.746 1.66 1.66 0 01-1.065.764 1.677 1.677 0 01-1.989-1.279c-.209-.906.332-1.83 1.257-2.043a1.51 1.51 0 01.296-.035h.018c.68-.071 1.151-.622 1.116-1.333a1.307 1.307 0 00-.227-.693 2.515 2.515 0 01-.366-1.403 2.39 2.39 0 01.366-1.208c.14-.195.21-.444.227-.693.018-.71-.506-1.261-1.186-1.332l-.07-.018a1.43 1.43 0 01-.299-.07l-.05-.019a1.7 1.7 0 01-1.047-2.114 1.68 1.68 0 012.094-1.101zm-5.575 10.11c.26-.264.639-.367.994-.27.355.096.633.379.728.74.095.362-.007.748-.267 1.013-.402.41-1.053.41-1.455 0a1.062 1.062 0 010-1.482zm14.845-.294c.359-.09.738.024.992.297.254.274.344.665.237 1.025-.107.36-.396.634-.756.718-.551.128-1.1-.22-1.23-.781a1.05 1.05 0 01.757-1.26zm-.064-4.39c.314.32.49.753.49 1.206 0 .452-.176.886-.49 1.206-.315.32-.74.5-1.185.5-.444 0-.87-.18-1.184-.5a1.727 1.727 0 010-2.412 1.654 1.654 0 012.369 0zm-11.243.163c.364.484.447 1.128.218 1.691a1.665 1.665 0 01-2.188.923c-.855-.36-1.26-1.358-.907-2.228a1.68 1.68 0 011.33-1.038c.593-.08 1.183.169 1.547.652zm11.545-4.221c.368 0 .708.2.892.524.184.324.184.724 0 1.048a1.026 1.026 0 01-.892.524c-.568 0-1.03-.47-1.03-1.048 0-.579.462-1.048 1.03-1.048zm-14.358 0c.368 0 .707.2.891.524.184.324.184.724 0 1.048a1.026 1.026 0 01-.891.524c-.569 0-1.03-.47-1.03-1.048 0-.579.461-1.048 1.03-1.048zm10.031-1.475c.925 0 1.675.764 1.675 1.706s-.75 1.705-1.675 1.705-1.674-.763-1.674-1.705c0-.942.75-1.706 1.674-1.706zm-2.626-.684c.362-.082.653-.356.761-.718a1.062 1.062 0 00-.238-1.028 1.017 1.017 0 00-.996-.294c-.547.14-.881.7-.752 1.257.13.558.675.907 1.225.783zm0 16.876c.359-.087.644-.36.75-.72a1.062 1.062 0 00-.237-1.019 1.018 1.018 0 00-.985-.301 1.037 1.037 0 00-.762.717c-.108.361-.017.754.239 1.028.245.263.606.377.953.305l.043-.01zM17.19 3.5a.631.631 0 00.628-.64c0-.355-.279-.64-.628-.64a.631.631 0 00-.628.64c0 .355.28.64.628.64zm-10.38 0a.631.631 0 00.628-.64c0-.355-.28-.64-.628-.64a.631.631 0 00-.628.64c0 .355.279.64.628.64zm-5.182 7.852a.631.631 0 00-.628.64c0 .354.28.639.628.639a.63.63 0 00.627-.606l.001-.034a.62.62 0 00-.628-.64zm5.182 9.13a.631.631 0 00-.628.64c0 .355.279.64.628.64a.631.631 0 00.628-.64c0-.355-.28-.64-.628-.64zm10.38.018a.631.631 0 00-.628.64c0 .355.28.64.628.64a.631.631 0 00.628-.64c0-.355-.279-.64-.628-.64zm5.182-9.148a.631.631 0 00-.628.64c0 .354.279.639.628.639a.631.631 0 00.628-.64c0-.355-.28-.64-.628-.64zm-.384-4.992a.24.24 0 00.244-.249.24.24 0 00-.244-.249.24.24 0 00-.244.249c0 .142.122.249.244.249zM11.991.497a.24.24 0 00.245-.248A.24.24 0 0011.99 0a.24.24 0 00-.244.249c0 .133.108.236.223.247l.021.001zM2.011 6.36a.24.24 0 00.245-.249.24.24 0 00-.244-.249.24.24 0 00-.244.249.24.24 0 00.244.249zm0 11.263a.24.24 0 00-.243.248.24.24 0 00.244.249.24.24 0 00.244-.249.252.252 0 00-.244-.248zm19.995-.018a.24.24 0 00-.245.248.24.24 0 00.245.25.24.24 0 00.244-.25.252.252 0 00-.244-.248z" fill="#3859FF" fill-rule="nonzero"></path></svg>',
|
|
20971
|
+
other: '<svg class="model-ico" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="24" rx="5" fill="#111111"/><g transform="translate(3.2 3.2) scale(0.733)"><path d="M18.654 3.87a5.087 5.087 0 110 10.174L23.7 19.09c.64.641.187 1.737-.72 1.737H8.48a8.479 8.479 0 010-16.958h10.175zM8.479 7.26a5.087 5.087 0 100 10.176 5.087 5.087 0 000-10.175z" fill="#C8FF00"></path></g></svg>'
|
|
20881
20972
|
};
|
|
20973
|
+
|
|
20974
|
+
// lib/finish/critique-code-web-icons.ts
|
|
20882
20975
|
function webModelProvider(modelId) {
|
|
20883
20976
|
const id4 = modelId.toLowerCase();
|
|
20884
20977
|
if (id4.includes("claude") || id4.includes("anthropic")) return "anthropic";
|
|
@@ -20897,17 +20990,10 @@ function webModelProvider(modelId) {
|
|
|
20897
20990
|
if (id4.includes("critique") || id4 === "auto" || id4.endsWith("/auto")) return "critique";
|
|
20898
20991
|
return "other";
|
|
20899
20992
|
}
|
|
20900
|
-
function webModelIconSvg(modelId, size = 16) {
|
|
20901
|
-
const provider = webModelProvider(modelId);
|
|
20902
|
-
const spec = ICONS[provider];
|
|
20903
|
-
const fg = provider === "xai" || provider === "kimi" ? "#111" : "#fff";
|
|
20904
|
-
const letter = spec.mark;
|
|
20905
|
-
return `<svg class="model-ico" width="${size}" height="${size}" viewBox="0 0 16 16" aria-hidden="true"><rect width="16" height="16" rx="4" fill="${spec.color}"/><text x="8" y="11.2" text-anchor="middle" font-size="8.5" font-weight="700" font-family="ui-sans-serif,system-ui,sans-serif" fill="${fg}">${letter}</text></svg>`;
|
|
20906
|
-
}
|
|
20907
20993
|
function webModelIconMap() {
|
|
20908
20994
|
const map = {};
|
|
20909
|
-
for (const provider of Object.keys(
|
|
20910
|
-
map[provider] =
|
|
20995
|
+
for (const provider of Object.keys(LOBE_MODEL_ICON_SVGS)) {
|
|
20996
|
+
map[provider] = LOBE_MODEL_ICON_SVGS[provider];
|
|
20911
20997
|
}
|
|
20912
20998
|
return map;
|
|
20913
20999
|
}
|
|
@@ -21307,17 +21393,18 @@ function critiqueCodeWebPage(input) {
|
|
|
21307
21393
|
const currentId = input.model.replace(/^critique\/critique\//, "critique/");
|
|
21308
21394
|
const options = models.map((entry) => {
|
|
21309
21395
|
const selected = entry.id === input.model || entry.id === currentId ? " selected" : "";
|
|
21310
|
-
|
|
21311
|
-
return `<option value="${escapeHtml(entry.id)}" data-provider="${webModelProvider(entry.id)}" data-icon="${escapeHtml(icon)}"${selected}>${escapeHtml(entry.label)}</option>`;
|
|
21396
|
+
return `<option value="${escapeHtml(entry.id)}" data-provider="${webModelProvider(entry.id)}"${selected}>${escapeHtml(entry.label)}</option>`;
|
|
21312
21397
|
}).join("");
|
|
21313
21398
|
return `<!DOCTYPE html>
|
|
21314
21399
|
<html lang="en">
|
|
21315
21400
|
<head>
|
|
21401
|
+
<script>try{if(localStorage.getItem("critique-code-theme")==="light")document.documentElement.setAttribute("data-theme","light")}catch(e){}</script>
|
|
21316
21402
|
<meta charset="utf-8">
|
|
21317
21403
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
21318
21404
|
<title>CritiqueCode</title>
|
|
21319
21405
|
<style>
|
|
21320
21406
|
:root {
|
|
21407
|
+
color-scheme:dark;
|
|
21321
21408
|
--bg:#0f0f0e;
|
|
21322
21409
|
--rail:#141412;
|
|
21323
21410
|
--surface:#181816;
|
|
@@ -21337,26 +21424,81 @@ function critiqueCodeWebPage(input) {
|
|
|
21337
21424
|
--primary:#f1ece4;
|
|
21338
21425
|
--primary-fg:#171613;
|
|
21339
21426
|
--shadow:0 24px 80px rgba(0,0,0,.48);
|
|
21427
|
+
--menu:#171715;
|
|
21428
|
+
--inset:#11110f;
|
|
21429
|
+
--code:#11110f;
|
|
21430
|
+
--term:#0d0d0c;
|
|
21431
|
+
--term-fg:#bbb4aa;
|
|
21432
|
+
--topbar:rgba(15,15,14,.86);
|
|
21433
|
+
--dock:linear-gradient(180deg,transparent,rgba(15,15,14,.96) 18%);
|
|
21434
|
+
--chip:rgba(255,255,255,.07);
|
|
21435
|
+
--wash:rgba(255,255,255,.03);
|
|
21436
|
+
--placeholder:#716b63;
|
|
21437
|
+
--link:#a9c8ff;
|
|
21438
|
+
--mono:#c5bdb1;
|
|
21439
|
+
--detail:#918a81;
|
|
21440
|
+
--reply:#e9e3da;
|
|
21441
|
+
--h4:#ddd6cc;
|
|
21442
|
+
--overlay:rgba(0,0,0,.55);
|
|
21443
|
+
--composer-shadow:0 16px 42px rgba(0,0,0,.25),inset 0 1px 0 rgba(255,255,255,.035);
|
|
21444
|
+
--diff-add-bg:rgba(85,216,140,.08);
|
|
21445
|
+
--diff-add-fg:#bae7ca;
|
|
21446
|
+
--diff-del-bg:rgba(239,119,112,.09);
|
|
21447
|
+
--diff-del-fg:#efc3c0;
|
|
21448
|
+
--diff-ctx:#aaa39a;
|
|
21449
|
+
--ln:#5e5953;
|
|
21450
|
+
--alert-fg:#f0b8b4;
|
|
21451
|
+
--review-fg:#d8e7dd;
|
|
21340
21452
|
--ease:cubic-bezier(.2,.8,.2,1);
|
|
21341
21453
|
--rail-w:252px;
|
|
21342
21454
|
--changes-w:390px;
|
|
21343
21455
|
--top-h:48px;
|
|
21344
21456
|
}
|
|
21345
21457
|
html[data-theme="light"]{
|
|
21346
|
-
|
|
21347
|
-
--
|
|
21458
|
+
color-scheme:light;
|
|
21459
|
+
--bg:#f3f1ec;
|
|
21460
|
+
--rail:#e8e4db;
|
|
21348
21461
|
--surface:#fff;
|
|
21349
|
-
--surface-2:#
|
|
21350
|
-
--surface-3:#
|
|
21351
|
-
--hover:rgba(
|
|
21352
|
-
--line:rgba(
|
|
21353
|
-
--line-strong:rgba(
|
|
21354
|
-
--fg:#
|
|
21355
|
-
--muted:#
|
|
21356
|
-
--faint:#
|
|
21357
|
-
--
|
|
21358
|
-
--
|
|
21359
|
-
--
|
|
21462
|
+
--surface-2:#efece5;
|
|
21463
|
+
--surface-3:#e3ded4;
|
|
21464
|
+
--hover:rgba(22,18,12,.07);
|
|
21465
|
+
--line:rgba(28,22,14,.14);
|
|
21466
|
+
--line-strong:rgba(28,22,14,.22);
|
|
21467
|
+
--fg:#16130f;
|
|
21468
|
+
--muted:#4a453e;
|
|
21469
|
+
--faint:#6a645c;
|
|
21470
|
+
--green:#1b8a52;
|
|
21471
|
+
--amber:#a36b0e;
|
|
21472
|
+
--red:#c4453e;
|
|
21473
|
+
--blue:#2d5db8;
|
|
21474
|
+
--primary:#16130f;
|
|
21475
|
+
--primary-fg:#faf8f3;
|
|
21476
|
+
--shadow:0 16px 44px rgba(40,28,12,.14);
|
|
21477
|
+
--menu:#ffffff;
|
|
21478
|
+
--inset:#f7f5f0;
|
|
21479
|
+
--code:#f6f3ec;
|
|
21480
|
+
--term:#f7f5f0;
|
|
21481
|
+
--term-fg:#3a352e;
|
|
21482
|
+
--topbar:rgba(243,241,236,.92);
|
|
21483
|
+
--dock:linear-gradient(180deg,transparent,rgba(243,241,236,.98) 20%);
|
|
21484
|
+
--chip:rgba(22,18,12,.07);
|
|
21485
|
+
--wash:rgba(22,18,12,.04);
|
|
21486
|
+
--placeholder:#7a746b;
|
|
21487
|
+
--link:#2453b0;
|
|
21488
|
+
--mono:#3a352e;
|
|
21489
|
+
--detail:#534e47;
|
|
21490
|
+
--reply:#1c1914;
|
|
21491
|
+
--h4:#3a352e;
|
|
21492
|
+
--overlay:rgba(28,22,14,.4);
|
|
21493
|
+
--composer-shadow:0 14px 36px rgba(40,28,12,.1),0 0 0 1px rgba(28,22,14,.04);
|
|
21494
|
+
--diff-add-bg:rgba(27,138,82,.12);
|
|
21495
|
+
--diff-add-fg:#145c37;
|
|
21496
|
+
--diff-del-bg:rgba(196,69,62,.12);
|
|
21497
|
+
--diff-del-fg:#922f2a;
|
|
21498
|
+
--diff-ctx:#4a453e;
|
|
21499
|
+
--ln:#8a8378;
|
|
21500
|
+
--alert-fg:#922f2a;
|
|
21501
|
+
--review-fg:#145c37;
|
|
21360
21502
|
}
|
|
21361
21503
|
*{box-sizing:border-box}
|
|
21362
21504
|
[hidden]{display:none!important}
|
|
@@ -21365,10 +21507,11 @@ button,input,textarea,select{font:inherit;color:inherit}
|
|
|
21365
21507
|
button{cursor:pointer}
|
|
21366
21508
|
button:focus-visible,input:focus-visible,textarea:focus-visible{outline:2px solid rgba(143,183,255,.75);outline-offset:2px}
|
|
21367
21509
|
.shell{display:grid;grid-template-columns:var(--rail-w) minmax(0,1fr) 1px var(--changes-w);height:100dvh;overflow:hidden}
|
|
21368
|
-
.shell.rail-off{--
|
|
21510
|
+
.shell.rail-off{grid-template-columns:minmax(0,1fr) 1px var(--changes-w)}
|
|
21369
21511
|
.shell.rail-off .rail{display:none}
|
|
21370
|
-
.shell.changes-off{--
|
|
21512
|
+
.shell.changes-off{grid-template-columns:var(--rail-w) minmax(0,1fr)}
|
|
21371
21513
|
.shell.changes-off .gutter,.shell.changes-off .changes{display:none}
|
|
21514
|
+
.shell.rail-off.changes-off{grid-template-columns:minmax(0,1fr)}
|
|
21372
21515
|
.shell.term-off .term{display:none}
|
|
21373
21516
|
.gutter{background:var(--line);cursor:col-resize}
|
|
21374
21517
|
|
|
@@ -21383,7 +21526,7 @@ button:focus-visible,input:focus-visible,textarea:focus-visible{outline:2px soli
|
|
|
21383
21526
|
.rail-search{position:relative}
|
|
21384
21527
|
.rail-search svg{position:absolute;left:10px;top:9px;color:var(--faint);pointer-events:none}
|
|
21385
21528
|
.rail .search{width:100%;height:34px;background:transparent;border:1px solid transparent;border-radius:8px;padding:0 10px 0 31px;color:var(--fg);outline:0;font-size:12px}
|
|
21386
|
-
.rail .search:focus{border-color:var(--line);background:
|
|
21529
|
+
.rail .search:focus{border-color:var(--line);background:var(--wash)}
|
|
21387
21530
|
#sessions{display:flex;flex-direction:column;gap:2px;min-height:0;overflow:auto;overscroll-behavior:contain;padding-right:1px;flex:1}
|
|
21388
21531
|
.session-row{display:grid;grid-template-columns:minmax(0,1fr) 28px;gap:2px;align-items:center;border-radius:8px}
|
|
21389
21532
|
.session-row:hover,.session-row.on{background:var(--hover)}
|
|
@@ -21399,14 +21542,14 @@ button:focus-visible,input:focus-visible,textarea:focus-visible{outline:2px soli
|
|
|
21399
21542
|
|
|
21400
21543
|
/* main */
|
|
21401
21544
|
.stage{display:grid;grid-template-rows:var(--top-h) minmax(0,1fr) auto auto;min-width:0;min-height:0;height:100dvh;overflow:hidden;background:var(--bg)}
|
|
21402
|
-
.topbar{height:var(--top-h);display:flex;align-items:center;gap:10px;padding:0 14px;border-bottom:1px solid var(--line);background:
|
|
21545
|
+
.topbar{height:var(--top-h);display:flex;align-items:center;gap:10px;padding:0 14px;border-bottom:1px solid var(--line);background:var(--topbar);backdrop-filter:blur(16px);z-index:2}
|
|
21403
21546
|
.topbar-left{display:flex;align-items:center;gap:9px;min-width:0;flex:1}
|
|
21404
21547
|
.session-title{min-width:0;font-size:12.5px;font-weight:600;color:var(--fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21405
21548
|
.top-actions{display:flex;align-items:center;gap:5px;min-width:0}
|
|
21406
21549
|
.icon-btn,.toolbar-btn{border:1px solid transparent;background:transparent;color:var(--muted);border-radius:8px;display:inline-flex;align-items:center;justify-content:center;gap:7px;height:30px;padding:0 8px;font-size:11.5px;white-space:nowrap}
|
|
21407
21550
|
.icon-btn{width:30px;padding:0}
|
|
21408
21551
|
.icon-btn:hover,.toolbar-btn:hover,.icon-btn.on,.toolbar-btn.on{background:var(--hover);color:var(--fg);border-color:var(--line)}
|
|
21409
|
-
.toolbar-btn .count{min-width:18px;height:18px;padding:0 5px;border-radius:999px;background:
|
|
21552
|
+
.toolbar-btn .count{min-width:18px;height:18px;padding:0 5px;border-radius:999px;background:var(--chip);display:inline-grid;place-items:center;color:var(--fg);font:10px ui-monospace,Menlo,monospace}
|
|
21410
21553
|
.top-status,.badge{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--faint);font-size:11px}
|
|
21411
21554
|
.badge.err{color:var(--red)}
|
|
21412
21555
|
#stop{color:var(--red);background:rgba(239,119,112,.08)}
|
|
@@ -21421,20 +21564,20 @@ main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:sta
|
|
|
21421
21564
|
#feed.on{display:block}
|
|
21422
21565
|
.turn{margin:0 0 34px;position:relative}
|
|
21423
21566
|
.prompt{max-width:82%;margin:0 0 18px auto;background:var(--surface-2);border:1px solid var(--line);border-radius:16px 16px 5px 16px;padding:11px 14px;line-height:1.5;white-space:pre-wrap;word-break:break-word;color:var(--fg);font-size:13.5px}
|
|
21424
|
-
.reply{margin:0;color
|
|
21567
|
+
.reply{margin:0;color:var(--reply);font-size:14px;line-height:1.63;word-break:break-word}
|
|
21425
21568
|
.reply>*:first-child{margin-top:0}.reply>*:last-child{margin-bottom:0}
|
|
21426
21569
|
.reply h1,.reply h2,.reply h3,.reply h4{color:var(--fg);font-weight:620;letter-spacing:-.03em;line-height:1.3;margin:20px 0 9px}
|
|
21427
|
-
.reply h1{font-size:19px}.reply h2{font-size:16.5px}.reply h3{font-size:14.5px}.reply h4{font-size:13.5px;color
|
|
21570
|
+
.reply h1{font-size:19px}.reply h2{font-size:16.5px}.reply h3{font-size:14.5px}.reply h4{font-size:13.5px;color:var(--h4)}
|
|
21428
21571
|
.reply p{margin:0 0 11px}.reply ul,.reply ol{margin:0 0 12px;padding-left:1.25em}.reply li{margin:0 0 4px}.reply li::marker{color:var(--faint)}
|
|
21429
|
-
.reply a{color
|
|
21430
|
-
.reply code{font:12px ui-monospace,Menlo,monospace;background:
|
|
21431
|
-
.reply blockquote{margin:0 0 12px;padding:7px 11px;border-left:2px solid var(--line-strong);color:var(--muted);background:
|
|
21572
|
+
.reply a{color:var(--link);text-decoration:none}.reply a:hover{text-decoration:underline}
|
|
21573
|
+
.reply code{font:12px ui-monospace,Menlo,monospace;background:var(--chip);border:1px solid var(--line);border-radius:5px;padding:1px 5px}
|
|
21574
|
+
.reply blockquote{margin:0 0 12px;padding:7px 11px;border-left:2px solid var(--line-strong);color:var(--muted);background:var(--wash)}
|
|
21432
21575
|
.reply hr{border:0;border-top:1px solid var(--line);margin:16px 0}
|
|
21433
|
-
.md-code{position:relative;background
|
|
21576
|
+
.md-code{position:relative;background:var(--code);border:1px solid var(--line);border-radius:10px;padding:30px 12px 12px;overflow:auto;font:12px ui-monospace,Menlo,monospace;line-height:1.55}
|
|
21434
21577
|
.md-code .copy{position:absolute;right:7px;top:7px;border:1px solid var(--line);background:var(--surface);color:var(--muted);border-radius:6px;padding:3px 7px;font-size:10.5px}
|
|
21435
21578
|
.reply .md-code code{background:none;border:0;padding:0}
|
|
21436
|
-
.md-table{margin:10px 0 14px;overflow:auto;border:1px solid var(--line);border-radius:10px;background
|
|
21437
|
-
.reply table{width:100%;border-collapse:collapse;font-size:12.5px}.reply th,.reply td{padding:8px 10px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)}.reply th{color:var(--muted);font-weight:600;font-size:11px;background:
|
|
21579
|
+
.md-table{margin:10px 0 14px;overflow:auto;border:1px solid var(--line);border-radius:10px;background:var(--code)}
|
|
21580
|
+
.reply table{width:100%;border-collapse:collapse;font-size:12.5px}.reply th,.reply td{padding:8px 10px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)}.reply th{color:var(--muted);font-weight:600;font-size:11px;background:var(--wash)}.reply tr:last-child td{border-bottom:0}
|
|
21438
21581
|
|
|
21439
21582
|
/* activity: each tool is its own row */
|
|
21440
21583
|
.activity{display:grid;gap:5px;margin:9px 0 13px}
|
|
@@ -21446,24 +21589,24 @@ main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:sta
|
|
|
21446
21589
|
.tool-event.running .tool-dot{background:var(--amber);box-shadow:0 0 0 3px rgba(224,170,67,.08)}
|
|
21447
21590
|
.tool-event.done .tool-dot{background:var(--green)}
|
|
21448
21591
|
.tool-event.failed .tool-dot{background:var(--red)}
|
|
21449
|
-
.tool-name{font-family:ui-monospace,Menlo,monospace;color
|
|
21592
|
+
.tool-name{font-family:ui-monospace,Menlo,monospace;color:var(--mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21450
21593
|
.tool-phase{color:var(--faint)}
|
|
21451
|
-
.tool-detail{margin:2px 0 4px 21px;max-width:min(680px,calc(100vw - 64px));padding:9px 10px;border-left:1px solid var(--line);color
|
|
21594
|
+
.tool-detail{margin:2px 0 4px 21px;max-width:min(680px,calc(100vw - 64px));padding:9px 10px;border-left:1px solid var(--line);color:var(--detail);white-space:pre-wrap;word-break:break-word;font:11px/1.5 ui-monospace,Menlo,monospace}
|
|
21452
21595
|
.think{margin:6px 0;color:var(--faint)}
|
|
21453
|
-
.think>div{margin:2px 0 4px 21px;padding-left:10px;border-left:1px solid var(--line);white-space:pre-wrap;word-break:break-word;font-size:11.5px;line-height:1.5;color
|
|
21596
|
+
.think>div{margin:2px 0 4px 21px;padding-left:10px;border-left:1px solid var(--line);white-space:pre-wrap;word-break:break-word;font-size:11.5px;line-height:1.5;color:var(--detail)}
|
|
21454
21597
|
.note,.alert,.review-card{margin:10px 0;padding:8px 10px;border-radius:8px;line-height:1.5;word-break:break-word;font-size:12px}
|
|
21455
21598
|
.note{padding:5px 2px;background:transparent;border:0;color:var(--faint);font-family:ui-monospace,Menlo,monospace}
|
|
21456
|
-
.alert{background:rgba(239,119,112,.07);border:1px solid rgba(239,119,112,.18);color
|
|
21457
|
-
.review-card{background:rgba(85,216,140,.045);border:1px solid rgba(85,216,140,.18);color
|
|
21599
|
+
.alert{background:rgba(239,119,112,.07);border:1px solid rgba(239,119,112,.18);color:var(--alert-fg)}
|
|
21600
|
+
.review-card{background:rgba(85,216,140,.045);border:1px solid rgba(85,216,140,.18);color:var(--review-fg)}
|
|
21458
21601
|
.trust{display:none}
|
|
21459
21602
|
.agent{margin:6px 0;padding:7px 9px;border-left:1px solid var(--line);color:var(--muted);font-size:11.5px}.agent.running{border-left-color:var(--amber)}.agent b{color:var(--fg);font-weight:560}
|
|
21460
21603
|
|
|
21461
21604
|
/* composer */
|
|
21462
|
-
.dock{padding:8px 18px 14px;background:
|
|
21463
|
-
.composer{position:relative;max-width:800px;margin:0 auto;background:var(--surface);border:1px solid var(--line-strong);border-radius:17px;padding:6px;box-shadow:
|
|
21605
|
+
.dock{padding:8px 18px 14px;background:var(--dock)}
|
|
21606
|
+
.composer{position:relative;max-width:800px;margin:0 auto;background:var(--surface);border:1px solid var(--line-strong);border-radius:17px;padding:6px;box-shadow:var(--composer-shadow)}
|
|
21464
21607
|
.composer-line{display:flex;align-items:flex-end;gap:5px}
|
|
21465
21608
|
.composer-line textarea{flex:1;min-width:0;width:100%;min-height:44px;max-height:190px;resize:none;background:transparent;border:0;padding:9px 7px;outline:0;line-height:1.5;font-size:14px;color:var(--fg)}
|
|
21466
|
-
.composer-line textarea::placeholder{color
|
|
21609
|
+
.composer-line textarea::placeholder{color:var(--placeholder)}
|
|
21467
21610
|
.round-btn,.plus-btn,.mic-btn{width:32px;height:32px;flex:0 0 auto;border:0;border-radius:9px;background:transparent;color:var(--muted);display:grid;place-items:center}
|
|
21468
21611
|
.round-btn:hover,.plus-btn:hover,.mic-btn:hover,.mic-btn.on{background:var(--hover);color:var(--fg)}
|
|
21469
21612
|
.composer-foot{display:flex;align-items:center;gap:6px;padding:3px 3px 1px;min-height:36px}
|
|
@@ -21473,12 +21616,12 @@ main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:sta
|
|
|
21473
21616
|
.pick-open:hover,#model-open:hover,.pick-open[aria-expanded="true"],#model-open[aria-expanded="true"]{background:var(--hover);border-color:var(--line);color:var(--fg)}
|
|
21474
21617
|
.pick-open .caret,#model-open .caret{opacity:.45;font-size:9px}
|
|
21475
21618
|
.model-ico{width:15px!important;height:15px!important;display:block;flex:0 0 auto;border-radius:4px}
|
|
21476
|
-
.model-fallback{width:15px;height:15px;display:inline-grid;place-items:center;border-radius:4px;background:
|
|
21477
|
-
.pick-menu,#model-menu,#mention,.cmd-pop,.branch-menu,.ship-menu{display:none;position:absolute;z-index:20;background
|
|
21619
|
+
.model-fallback{width:15px;height:15px;display:inline-grid;place-items:center;border-radius:4px;background:var(--chip);color:var(--fg);font:700 8px ui-monospace,Menlo,monospace;flex:0 0 auto}
|
|
21620
|
+
.pick-menu,#model-menu,#mention,.cmd-pop,.branch-menu,.ship-menu{display:none;position:absolute;z-index:20;background:var(--menu);border:1px solid var(--line-strong);border-radius:12px;box-shadow:var(--shadow);overflow:hidden}
|
|
21478
21621
|
.pick-menu.open,#model-menu.open,#mention.open,.cmd-pop.open,.branch-menu.open,.ship-menu.open{display:grid}
|
|
21479
21622
|
.pick-menu{bottom:36px;left:0;min-width:210px;max-height:300px;overflow:auto;overscroll-behavior:contain;padding:5px}
|
|
21480
21623
|
#model-menu{right:0;bottom:36px;width:310px;max-height:360px;grid-template-rows:auto minmax(0,1fr);overscroll-behavior:contain}
|
|
21481
|
-
#model-filter{width:100%;height:39px;background
|
|
21624
|
+
#model-filter{width:100%;height:39px;background:var(--inset);border:0;border-bottom:1px solid var(--line);padding:0 11px;outline:0;font-size:12px}
|
|
21482
21625
|
#model-list{overflow:auto;overscroll-behavior:contain;max-height:310px;padding:5px}
|
|
21483
21626
|
.pick-menu button,#model-list button,#mention-list button{width:100%;min-height:34px;border:0;background:transparent;color:var(--muted);border-radius:8px;padding:7px 9px;text-align:left;display:flex;align-items:center;gap:8px;font-size:11.5px}
|
|
21484
21627
|
.pick-menu button:hover,.pick-menu button.on,#model-list button:hover,#model-list button.on,#mention-list button:hover,#mention-list button.on{background:var(--hover);color:var(--fg)}
|
|
@@ -21487,37 +21630,37 @@ main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:sta
|
|
|
21487
21630
|
#send:hover{transform:translateY(-1px);filter:brightness(1.04)}#send.steer{background:#bfe8cf;color:#142219}#send:disabled{opacity:.45;cursor:not-allowed}
|
|
21488
21631
|
#review-run{height:30px;padding:0 10px;border:1px solid var(--line);border-radius:8px;background:transparent;color:var(--muted);font-size:11.5px}#review-run:hover{background:var(--hover);color:var(--fg)}
|
|
21489
21632
|
.autonomy-pill.auto{color:var(--amber);border-color:rgba(224,170,67,.24);background:rgba(224,170,67,.055)}
|
|
21490
|
-
.chips{display:flex;flex-wrap:wrap;gap:4px;padding:0 7px 4px}.chip{display:inline-flex;align-items:center;gap:5px;border-radius:7px;background:
|
|
21491
|
-
.queue{margin:2px 5px 6px;border:1px solid var(--line);border-radius:10px;background
|
|
21633
|
+
.chips{display:flex;flex-wrap:wrap;gap:4px;padding:0 7px 4px}.chip{display:inline-flex;align-items:center;gap:5px;border-radius:7px;background:var(--chip);padding:3px 7px;color:var(--muted);font-size:10.5px;cursor:pointer}.chip-img{padding:3px 7px 3px 3px}.chip-img img{width:36px;height:36px;object-fit:cover;border-radius:5px;background:var(--inset)}
|
|
21634
|
+
.queue{margin:2px 5px 6px;border:1px solid var(--line);border-radius:10px;background:var(--inset)}.queue-item{padding:8px 10px;color:var(--fg);font-size:12px;white-space:pre-wrap;border-bottom:1px solid var(--line)}.queue-item button{float:right;border:0;background:transparent;color:var(--faint);font-size:10px}.queue-bar{display:flex;align-items:center;justify-content:space-between;padding:6px 9px;color:var(--muted);font-size:10.5px}.queue-bar button{border:0;background:transparent;color:var(--muted);font-size:10.5px}.queue-bar .now{color:var(--fg)}
|
|
21492
21635
|
.cmds{position:relative}.cmd-pop{left:0;bottom:38px;width:220px;padding:5px}.cmd-pop button{height:34px;border:0;background:transparent;color:var(--muted);border-radius:8px;padding:0 9px;text-align:left;font-size:11.5px}.cmd-pop button:hover{background:var(--hover);color:var(--fg)}
|
|
21493
21636
|
#mention{left:8px;bottom:calc(100% - 4px);width:min(500px,calc(100% - 16px));max-height:330px}#mention-list{overflow:auto;overscroll-behavior:contain;padding:5px}.mention-k{font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);padding:7px 9px 3px}.pick-menu button .meta,#mention-list button .meta{margin-left:auto;color:var(--faint);font-size:10px}
|
|
21494
21637
|
|
|
21495
21638
|
/* terminal */
|
|
21496
|
-
.term{border-top:1px solid var(--line);background
|
|
21639
|
+
.term{border-top:1px solid var(--line);background:var(--term);display:grid;grid-template-rows:auto minmax(70px,1fr) auto;max-height:220px}.term header{height:32px;display:flex;align-items:center;justify-content:space-between;padding:0 10px;color:var(--faint);font-size:10.5px}.term header>span{display:flex;align-items:center;gap:6px}.term pre{margin:0;padding:8px 11px;overflow:auto;overscroll-behavior:contain;font:11px/1.5 ui-monospace,Menlo,monospace;color:var(--term-fg)}.term form{display:flex;padding:5px 8px 8px}.term input{flex:1;height:31px;background:var(--inset);border:1px solid var(--line);border-radius:7px;padding:0 9px;outline:0;font:11px ui-monospace,Menlo,monospace}.term button{border:0;background:transparent;color:var(--muted);font-size:10.5px}.term .pick-menu{bottom:auto;top:30px}.always-row{display:flex;align-items:center;gap:7px;color:var(--muted);font-size:11px}.always-row input{accent-color:var(--amber)}
|
|
21497
21640
|
|
|
21498
21641
|
/* workspace */
|
|
21499
|
-
.changes{min-width:0;min-height:0;height:100dvh;background:var(--rail);border-left:1px solid var(--line);display:grid;grid-template-rows:auto auto minmax(0,1fr);overflow:hidden}.changes>header{padding:11px 10px 8px;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:3px 8px;align-items:center}.changes h2{margin:0;font-size:12.5px;font-weight:620}.changes .sum{grid-column:1/-1;color:var(--faint);font:10.5px ui-monospace,Menlo,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.work-tabs{display:flex;gap:2px;padding:0 7px 7px;border-bottom:1px solid var(--line)}.work-tabs button{height:27px;border:0;background:transparent;color:var(--muted);font-size:10.5px;border-radius:7px;padding:0 8px}.work-tabs button.on{background:var(--hover);color:var(--fg)}.work-stack{min-height:0;overflow:hidden;display:grid}.work-stack>*{min-height:0;height:100%}.workspace{min-height:0;padding:7px;display:grid;gap:6px;overflow:hidden}.workspace input{width:100%;height:32px;background
|
|
21500
|
-
#tab-tree{grid-template-rows:auto minmax(110px,.8fr) auto minmax(180px,1.25fr)}#tab-findings,#tab-timeline{grid-template-rows:auto minmax(0,1fr)}.diff-head{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:7px;align-items:center;padding:5px 2px}.diff-title-wrap{min-width:0;display:flex;align-items:center;gap:8px}.diff-back{flex:0 0 auto;border:0;background:transparent;color:var(--muted);padding:3px 5px;border-radius:6px;font-size:10.5px}.diff-back:hover{color:var(--fg);background:var(--hover)}.diff-head b,#diff-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:10.5px ui-monospace,Menlo,monospace;color:var(--fg)}.diff-actions{display:flex;gap:4px}.diff-actions button{height:27px;border:1px solid var(--line);background:transparent;border-radius:7px;padding:0 7px;color:var(--muted);font-size:10px}.diff-actions button:hover{background:var(--hover);color:var(--fg)}.diff-actions .danger{color:var(--red)}.diff{min-height:0;overflow:auto;overscroll-behavior:contain;padding-bottom:14px;border:1px solid var(--line);border-radius:8px;background
|
|
21642
|
+
.changes{min-width:0;min-height:0;height:100dvh;background:var(--rail);border-left:1px solid var(--line);display:grid;grid-template-rows:auto auto minmax(0,1fr);overflow:hidden}.changes>header{padding:11px 10px 8px;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:3px 8px;align-items:center}.changes h2{margin:0;font-size:12.5px;font-weight:620}.changes .sum{grid-column:1/-1;color:var(--faint);font:10.5px ui-monospace,Menlo,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.work-tabs{display:flex;gap:2px;padding:0 7px 7px;border-bottom:1px solid var(--line)}.work-tabs button{height:27px;border:0;background:transparent;color:var(--muted);font-size:10.5px;border-radius:7px;padding:0 8px}.work-tabs button.on{background:var(--hover);color:var(--fg)}.work-stack{min-height:0;overflow:hidden;display:grid}.work-stack>*{min-height:0;height:100%}.workspace{min-height:0;padding:7px;display:grid;gap:6px;overflow:hidden}.workspace input{width:100%;height:32px;background:var(--inset);border:1px solid var(--line);border-radius:8px;padding:0 9px;outline:0;font-size:11px}.tree{min-height:0;overflow:auto;overscroll-behavior:contain;font:11px ui-monospace,Menlo,monospace}.tree button{width:100%;min-height:27px;border:0;background:transparent;color:var(--muted);border-radius:6px;text-align:left;display:flex;align-items:center;gap:6px;padding:4px 6px}.tree button:hover,.tree button.on{background:var(--hover);color:var(--fg)}.tree .twist{width:9px;flex:0 0 auto;opacity:.55;font-size:8px}.tree .kind-untracked,.tree .kind-added{color:var(--green)}.tree .kind-modified{color:var(--amber)}.tree .kind-deleted{color:var(--red);text-decoration:line-through}.tree .kind-renamed{color:var(--blue)}
|
|
21643
|
+
#tab-tree{grid-template-rows:auto minmax(110px,.8fr) auto minmax(180px,1.25fr)}#tab-findings,#tab-timeline{grid-template-rows:auto minmax(0,1fr)}.diff-head{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:7px;align-items:center;padding:5px 2px}.diff-title-wrap{min-width:0;display:flex;align-items:center;gap:8px}.diff-back{flex:0 0 auto;border:0;background:transparent;color:var(--muted);padding:3px 5px;border-radius:6px;font-size:10.5px}.diff-back:hover{color:var(--fg);background:var(--hover)}.diff-head b,#diff-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:10.5px ui-monospace,Menlo,monospace;color:var(--fg)}.diff-actions{display:flex;gap:4px}.diff-actions button{height:27px;border:1px solid var(--line);background:transparent;border-radius:7px;padding:0 7px;color:var(--muted);font-size:10px}.diff-actions button:hover{background:var(--hover);color:var(--fg)}.diff-actions .danger{color:var(--red)}.diff{min-height:0;overflow:auto;overscroll-behavior:contain;padding-bottom:14px;border:1px solid var(--line);border-radius:8px;background:var(--code);font:11px/1.5 ui-monospace,Menlo,monospace}.diff-file+.diff-file{border-top:1px solid var(--line-strong);margin-top:10px;padding-top:5px}.diff-file-head{position:sticky;top:0;z-index:2;padding:8px 10px;background:var(--surface-2);border-bottom:1px solid var(--line);color:var(--fg);font:600 11px ui-monospace,Menlo,monospace}.diff-loading{padding:14px;color:var(--faint);font-size:11px}.diff .hunk{color:var(--faint);padding:6px 8px 3px;background:var(--wash)}.diff .row{display:grid;grid-template-columns:36px 36px minmax(0,1fr)}.diff .ln{color:var(--ln);text-align:right;padding:0 6px;user-select:none}.diff .add{background:var(--diff-add-bg);color:var(--diff-add-fg)}.diff .del{background:var(--diff-del-bg);color:var(--diff-del-fg)}.diff .ctx{color:var(--diff-ctx)}.diff .code{white-space:pre-wrap;word-break:break-word;padding-right:7px}#file-view{margin:0;white-space:pre-wrap;font:11px/1.5 ui-monospace,Menlo,monospace;padding:10px;color:var(--muted);overflow:auto;border:1px solid var(--line);border-radius:8px;background:var(--code)}#preview{width:100%;height:100%;min-height:0;border:0;background:#fff;border-radius:8px}.compare{display:grid;grid-template-columns:1fr 1fr;gap:7px;padding:8px;font:11px ui-monospace,Menlo,monospace;overflow:auto}.find-row{width:100%;text-align:left;border:0;background:transparent;color:var(--muted);padding:7px;border-radius:7px;font-size:11px}.find-row:hover{background:var(--hover);color:var(--fg)}.change-list{display:none}.gate{display:none}
|
|
21501
21644
|
|
|
21502
21645
|
/* overlays */
|
|
21503
|
-
.sheet{display:none;position:fixed;inset:0;z-index:50;background:
|
|
21504
|
-
#modal{display:none;position:fixed;inset:0;z-index:60;background:
|
|
21505
|
-
.palette{display:none;position:fixed;z-index:65;inset:12vh 0 auto;margin:auto;width:min(560px,92vw);background
|
|
21646
|
+
.sheet{display:none;position:fixed;inset:0;z-index:50;background:var(--overlay);align-items:center;justify-content:center;padding:20px;backdrop-filter:blur(4px)}.sheet.open{display:flex}.sheet .card{width:min(640px,95vw);max-height:84vh;overflow:auto;overscroll-behavior:contain;background:var(--menu);border:1px solid var(--line-strong);border-radius:14px;padding:16px;box-shadow:var(--shadow)}.sheet h3{margin:0 0 12px;font-size:15px}.sheet label{display:block;color:var(--muted);font-size:11px;margin:9px 0 4px}.sheet input,.sheet select,.sheet textarea.plain{width:100%;background:var(--inset);border:1px solid var(--line);border-radius:8px;padding:8px;outline:0}.modal-actions{display:flex;justify-content:flex-end;gap:7px;flex-wrap:wrap;margin-top:12px}.modal-actions button{min-height:32px;border:1px solid var(--line);background:var(--surface);border-radius:8px;padding:0 10px;color:var(--muted)}.modal-actions button:hover{color:var(--fg);border-color:var(--line-strong)}.modal-actions .deny{color:var(--red)}
|
|
21647
|
+
#modal{display:none;position:fixed;inset:0;z-index:60;background:var(--overlay);align-items:center;justify-content:center;padding:20px}#modal.open{display:flex}.dialog{width:min(520px,100%);background:var(--menu);border:1px solid var(--line-strong);border-radius:14px;padding:16px;box-shadow:var(--shadow)}.dialog h3{margin:0 0 7px;font-size:15px}.dialog .purpose{color:var(--muted);font-size:12px}.preview{max-height:240px;overflow:auto;overscroll-behavior:contain;white-space:pre-wrap;word-break:break-word;margin:11px 0 14px;padding:10px;background:var(--inset);border:1px solid var(--line);border-radius:8px;font:11px/1.5 ui-monospace,Menlo,monospace;color:var(--muted)}
|
|
21648
|
+
.palette{display:none;position:fixed;z-index:65;inset:12vh 0 auto;margin:auto;width:min(560px,92vw);background:var(--menu);border:1px solid var(--line-strong);border-radius:13px;padding:7px;box-shadow:var(--shadow)}.palette.open{display:block}.palette input{width:100%;height:39px;background:var(--inset);border:1px solid var(--line);border-radius:8px;padding:0 10px;outline:0}.palette button{width:100%;min-height:34px;border:0;background:transparent;color:var(--muted);text-align:left;border-radius:8px;padding:6px 8px;font-size:11.5px}.palette button:hover{background:var(--hover);color:var(--fg)}
|
|
21506
21649
|
|
|
21507
21650
|
/* command browser */
|
|
21508
|
-
.command-card{width:min(720px,95vw)!important;padding:0!important;overflow:hidden!important}.sheet-head{height:50px;padding:0 15px;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between}.sheet-head h3{margin:0}.sheet-head button{border:0;background:transparent;color:var(--muted);width:30px;height:30px;border-radius:7px}.sheet-head button:hover{background:var(--hover);color:var(--fg)}.command-body{padding:12px;display:grid;grid-template-rows:auto minmax(0,1fr);gap:9px;max-height:72vh}.command-body input{margin:0}.command-list{min-height:0;overflow:auto;overscroll-behavior:contain;display:grid;gap:3px}.command-row{display:grid;grid-template-columns:140px minmax(0,1fr) auto;gap:10px;align-items:start;border:0;background:transparent;border-radius:9px;padding:9px 10px;text-align:left;color:var(--muted)}.command-row:hover{background:var(--hover);color:var(--fg)}.command-code{font:11px ui-monospace,Menlo,monospace;color
|
|
21651
|
+
.command-card{width:min(720px,95vw)!important;padding:0!important;overflow:hidden!important}.sheet-head{height:50px;padding:0 15px;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between}.sheet-head h3{margin:0}.sheet-head button{border:0;background:transparent;color:var(--muted);width:30px;height:30px;border-radius:7px}.sheet-head button:hover{background:var(--hover);color:var(--fg)}.command-body{padding:12px;display:grid;grid-template-rows:auto minmax(0,1fr);gap:9px;max-height:72vh}.command-body input{margin:0}.command-list{min-height:0;overflow:auto;overscroll-behavior:contain;display:grid;gap:3px}.command-row{display:grid;grid-template-columns:140px minmax(0,1fr) auto;gap:10px;align-items:start;border:0;background:transparent;border-radius:9px;padding:9px 10px;text-align:left;color:var(--muted)}.command-row:hover{background:var(--hover);color:var(--fg)}.command-code{font:11px ui-monospace,Menlo,monospace;color:var(--mono)}.command-desc{font-size:11.5px;line-height:1.4}.command-kind{font-size:9.5px;color:var(--faint);text-transform:uppercase;letter-spacing:.06em}
|
|
21509
21652
|
|
|
21510
21653
|
/* settings */
|
|
21511
|
-
.settings-card{width:min(980px,96vw)!important;height:min(720px,92vh);max-height:92vh!important;padding:0!important;overflow:hidden!important;display:grid;grid-template-columns:190px minmax(0,1fr);background
|
|
21512
|
-
.usage-cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin:14px 0 18px}.usage-card{border:1px solid var(--line);border-radius:10px;padding:10px;background:
|
|
21513
|
-
.skill-list{display:grid;gap:7px}.skill-row{border:1px solid var(--line);border-radius:9px;padding:10px 11px;background:
|
|
21654
|
+
.settings-card{width:min(980px,96vw)!important;height:min(720px,92vh);max-height:92vh!important;padding:0!important;overflow:hidden!important;display:grid;grid-template-columns:190px minmax(0,1fr);background:var(--menu)!important}.settings-nav{border-right:1px solid var(--line);padding:13px 9px;display:flex;flex-direction:column;gap:3px;min-height:0}.settings-nav-head{display:flex;align-items:center;justify-content:space-between;padding:4px 7px 12px}.settings-nav-head b{font-size:13px}.settings-nav button[data-settings-tab]{height:33px;border:0;background:transparent;color:var(--muted);border-radius:8px;text-align:left;padding:0 9px;font-size:11.5px}.settings-nav button[data-settings-tab]:hover,.settings-nav button[data-settings-tab].on{background:var(--hover);color:var(--fg)}.settings-close{width:28px;height:28px;border:0;background:transparent;color:var(--muted);border-radius:7px}.settings-close:hover{background:var(--hover);color:var(--fg)}.settings-content{min-width:0;min-height:0;overflow:auto;overscroll-behavior:contain;padding:24px 26px 34px}.settings-panel{display:none;max-width:720px}.settings-panel.on{display:block}.settings-panel h2{margin:0 0 4px;font-size:18px;letter-spacing:-.03em}.settings-panel>.sub{margin:0 0 22px;color:var(--muted);font-size:12px;line-height:1.5}.setting-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:24px;align-items:center;padding:13px 0;border-top:1px solid var(--line)}.setting-copy b{display:block;font-size:12.5px;font-weight:580;margin-bottom:3px}.setting-copy span{display:block;color:var(--muted);font-size:11.5px;line-height:1.45}.setting-control{min-width:190px;display:flex;justify-content:flex-end}.setting-control .pick-menu{bottom:auto;top:36px;right:0;left:auto;max-height:300px;overflow:auto;overscroll-behavior:contain}.setting-control .pick-open{border-color:var(--line);background:var(--wash);min-width:180px;justify-content:space-between}.setting-control input[type=password]{width:240px;height:34px;background:var(--inset);border:1px solid var(--line);border-radius:8px;padding:0 9px}.settings-note{border:1px solid var(--line);background:var(--wash);border-radius:9px;padding:10px 11px;color:var(--muted);font-size:11.5px;line-height:1.5}.settings-note.warn{border-color:rgba(224,170,67,.22);background:rgba(224,170,67,.045)}
|
|
21655
|
+
.usage-cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin:14px 0 18px}.usage-card{border:1px solid var(--line);border-radius:10px;padding:10px;background:var(--wash)}.usage-card span{display:block;color:var(--faint);font-size:9.5px;text-transform:uppercase;letter-spacing:.06em;margin-bottom:6px}.usage-card b{font:600 17px ui-monospace,Menlo,monospace;color:var(--fg)}.usage-chart{height:180px;border:1px solid var(--line);border-radius:10px;background:var(--code);padding:9px;margin-bottom:16px}.usage-chart svg{display:block;width:100%;height:100%;overflow:visible;color:var(--muted)}.usage-empty{height:100%;display:grid;place-items:center;color:var(--faint);font-size:11px}.breakdown{display:grid;gap:7px;margin:8px 0 20px}.break-row{display:grid;grid-template-columns:120px minmax(0,1fr) 90px;gap:9px;align-items:center;font-size:10.5px;color:var(--muted)}.break-track{height:6px;background:var(--chip);border-radius:999px;overflow:hidden}.break-fill{height:100%;background:var(--muted);border-radius:999px}.break-val{text-align:right;font:10.5px ui-monospace,Menlo,monospace;color:var(--faint)}
|
|
21656
|
+
.skill-list{display:grid;gap:7px}.skill-row{border:1px solid var(--line);border-radius:9px;padding:10px 11px;background:var(--wash)}.skill-head{display:flex;align-items:center;gap:8px;margin-bottom:4px}.skill-head b{font-size:12px}.skill-source{padding:2px 6px;border-radius:999px;background:var(--chip);color:var(--faint);font-size:9.5px}.skill-desc{color:var(--muted);font-size:11.5px;line-height:1.45}.skill-origin{margin-top:5px;color:var(--faint);font:9.5px ui-monospace,Menlo,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.audit-list{display:grid;gap:5px}.audit-row{display:grid;grid-template-columns:120px 90px minmax(0,1fr);gap:8px;padding:7px 0;border-top:1px solid var(--line);color:var(--muted);font-size:10.5px}.audit-row code{color:var(--mono);font-size:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21514
21657
|
#mode,#autonomy,#thinking,#review-depth,#review-lens,#term-timeout,#studio-author,#studio-review,#key-kind{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.hidden-config{display:none!important}
|
|
21515
21658
|
.branch-menu{left:0;bottom:36px;min-width:220px;max-height:260px;overflow:auto;overscroll-behavior:contain;padding:5px}.branch-menu button,.ship-menu button{width:100%;border:0;background:transparent;color:var(--muted);padding:7px 9px;text-align:left;border-radius:7px;font-size:11px}.branch-menu button:hover,.ship-menu button:hover{background:var(--hover);color:var(--fg)}.ship-menu{right:0;bottom:36px;min-width:210px;padding:5px}.ship-wrap{position:relative}.meta-btn{height:29px;border:1px solid var(--line);background:transparent;border-radius:8px;padding:0 8px;color:var(--muted);font-size:10.5px}.meta-btn:hover{background:var(--hover);color:var(--fg)}
|
|
21516
21659
|
|
|
21517
21660
|
/* resume picker */
|
|
21518
|
-
.resume-picker{border-radius:14px;background
|
|
21661
|
+
.resume-picker{border-radius:14px;background:var(--menu);overflow:hidden;border:1px solid var(--line)}.resume-head{display:flex;justify-content:space-between;align-items:center;padding:11px 13px;border-bottom:1px solid var(--line)}.resume-head strong{font-size:12px;font-weight:600}.resume-head span{color:var(--faint);font-size:10.5px}.resume-list{padding:5px;max-height:330px;overflow:auto;overscroll-behavior:contain}.resume-chat{width:100%;border:0;background:transparent;color:var(--fg);padding:9px 10px;border-radius:8px;display:flex;align-items:center;gap:12px;text-align:left}.resume-chat:hover{background:var(--hover)}.resume-copy{min-width:0;flex:1;display:grid;gap:3px}.resume-copy strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:500}.resume-copy span{color:var(--faint);font-size:10px}.resume-arrow{color:var(--faint);font-size:18px}.resume-empty{padding:18px 12px;color:var(--faint);text-align:center;font-size:11px}
|
|
21519
21662
|
|
|
21520
|
-
@media(max-width:1100px){.shell,.shell.
|
|
21663
|
+
@media(max-width:1100px){.shell,.shell.changes-off{grid-template-columns:var(--rail-w) minmax(0,1fr)}.shell.rail-off,.shell.rail-off.changes-off{grid-template-columns:minmax(0,1fr)}.gutter{display:none}.changes{display:none}.shell:not(.changes-off) .changes,.changes.open{display:grid;position:fixed;inset:0 0 0 auto;width:min(420px,100%);z-index:40;box-shadow:-18px 0 50px rgba(0,0,0,.45)}}
|
|
21521
21664
|
@media(max-width:760px){:root{--top-h:46px}.shell,.shell.rail-off{grid-template-columns:1fr}.rail{display:none}.shell:not(.rail-off) .rail{display:flex;position:fixed;inset:0 auto 0 0;width:min(285px,88vw);z-index:45;box-shadow:20px 0 50px rgba(0,0,0,.5)}.topbar{padding:0 10px}.top-actions .toolbar-label{display:none}.top-actions{gap:2px}.toolbar-btn{padding:0 7px}.dock{padding:6px 9px calc(10px + env(safe-area-inset-bottom))}.composer{border-radius:15px}.composer-line textarea{font-size:16px;min-height:46px}.composer-foot{padding-top:2px}.composer-left .pick[data-pick="mode"],.composer-left .pick[data-pick="autonomy"]{display:none}#model-open{max-width:155px}.prompt{max-width:90%;font-size:13.5px}#feed{padding:22px 15px 30px}.settings-card{width:100vw!important;height:100dvh;max-height:100dvh!important;border-radius:0!important;border:0!important;grid-template-columns:1fr}.settings-nav{border-right:0;border-bottom:1px solid var(--line);padding:8px;display:grid;grid-template-columns:1fr auto;gap:5px}.settings-nav-head{grid-column:1/-1;padding:2px 4px 4px}.settings-nav button[data-settings-tab]{display:none}.settings-nav button[data-settings-tab].on{display:none}.settings-mobile-tabs{display:flex!important;grid-column:1/-1;gap:3px;overflow:auto;padding-bottom:1px}.settings-mobile-tabs button{display:block!important;flex:0 0 auto;height:29px!important;padding:0 8px!important}.settings-content{padding:18px 15px 30px}.setting-row{grid-template-columns:1fr;gap:8px}.setting-control{justify-content:flex-start;min-width:0}.setting-control .pick-open{width:100%;max-width:100%}.setting-control .pick{width:100%}.setting-control .pick-menu{left:0;right:auto;width:100%;max-width:100%}.usage-cards{grid-template-columns:1fr 1fr}.break-row{grid-template-columns:88px minmax(0,1fr) 68px}.command-row{grid-template-columns:110px minmax(0,1fr)}.command-kind{display:none}.sheet{padding:0}.command-card{width:100vw!important;height:100dvh;max-height:100dvh!important;border-radius:0!important}.command-body{max-height:calc(100dvh - 50px)}#empty{margin-top:12vh;padding:0 18px}.top-status{display:none}.diff-head{min-height:39px;gap:6px}.diff-title-wrap{overflow:hidden}#diff-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.diff-actions{overflow-x:auto;max-width:52vw;scrollbar-width:none}.diff-actions::-webkit-scrollbar{display:none}.diff-actions button{flex:0 0 auto}.diff,#file-view{border-radius:10px;font-size:10.5px}.diff .row{grid-template-columns:30px 30px minmax(0,1fr)}.diff .ln{padding:0 4px}.diff-file-head{padding:8px}.resume-picker{width:100%;margin:12px 0 24px;border-radius:12px}.resume-list{max-height:min(360px,48dvh)}.resume-chat{min-height:48px}}
|
|
21522
21665
|
</style>
|
|
21523
21666
|
</head>
|
|
@@ -21623,7 +21766,7 @@ main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:sta
|
|
|
21623
21766
|
<button type="button" data-cmd="/login">Login / connect inference</button>
|
|
21624
21767
|
</div>
|
|
21625
21768
|
</div>
|
|
21626
|
-
<textarea id="input" rows="1" placeholder="Message CritiqueCode\u2026" title="Type / for commands and skills, @ to add context"></textarea>
|
|
21769
|
+
<textarea id="input" rows="1" placeholder="Message CritiqueCode\u2026 Paste or drop an image." title="Type / for commands and skills, @ to add context. Paste a screenshot to attach it."></textarea>
|
|
21627
21770
|
<button type="button" class="mic-btn" id="voice" title="Voice input" aria-label="Voice input">
|
|
21628
21771
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="5" y="2" width="4" height="7" rx="2" stroke="currentColor" stroke-width="1.2"/><path d="M3.5 7.5a3.5 3.5 0 0 0 7 0M7 11v1.5" stroke="currentColor" stroke-width="1.2"/></svg>
|
|
21629
21772
|
</button>
|
|
@@ -21796,6 +21939,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
21796
21939
|
var sessionTitleEl = document.getElementById("session-title");
|
|
21797
21940
|
var activeSessionId = null;
|
|
21798
21941
|
var refs = [];
|
|
21942
|
+
var pendingImages = [];
|
|
21799
21943
|
var sessionMentions = [];
|
|
21800
21944
|
var treePaths = [];
|
|
21801
21945
|
var collapsedDirs = {};
|
|
@@ -21896,7 +22040,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
21896
22040
|
|
|
21897
22041
|
function modelIconHtml(option) {
|
|
21898
22042
|
var provider = option && (option.getAttribute("data-provider") || "") || "other";
|
|
21899
|
-
var raw =
|
|
22043
|
+
var raw = iconMap[provider] || iconMap.other || "";
|
|
21900
22044
|
if (raw) return raw;
|
|
21901
22045
|
var label = option && (option.text || option.value) || provider || "model";
|
|
21902
22046
|
var letter = String(label).replace(/^[^a-z0-9]+/i, "").charAt(0).toUpperCase() || "M";
|
|
@@ -21999,7 +22143,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
21999
22143
|
btn.type = "button";
|
|
22000
22144
|
btn.className = option.selected ? "on" : "";
|
|
22001
22145
|
btn.textContent = "";
|
|
22002
|
-
var icon = option.getAttribute("data-
|
|
22146
|
+
var icon = option.getAttribute("data-provider") ? modelIconHtml(option) : "";
|
|
22003
22147
|
if (icon) btn.insertAdjacentHTML("beforeend", icon);
|
|
22004
22148
|
var name = document.createElement("span");
|
|
22005
22149
|
name.textContent = option.text || option.value;
|
|
@@ -22286,7 +22430,8 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22286
22430
|
promptQueue.forEach(function (item, index) {
|
|
22287
22431
|
var row = document.createElement("div");
|
|
22288
22432
|
row.className = "queue-item";
|
|
22289
|
-
|
|
22433
|
+
var labelText = typeof item === "string" ? item : (item.text || (item.images && item.images.length ? item.images.length + " image" : ""));
|
|
22434
|
+
row.textContent = labelText;
|
|
22290
22435
|
var rm = document.createElement("button");
|
|
22291
22436
|
rm.type = "button";
|
|
22292
22437
|
rm.textContent = "Remove";
|
|
@@ -22301,12 +22446,13 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22301
22446
|
label.textContent = n ? n + " Queued \u21B5 to Send" : "";
|
|
22302
22447
|
}
|
|
22303
22448
|
|
|
22304
|
-
function enqueuePrompt(text) {
|
|
22305
|
-
promptQueue.push(text);
|
|
22449
|
+
function enqueuePrompt(text, images) {
|
|
22450
|
+
promptQueue.push({ text: text, images: images || [] });
|
|
22306
22451
|
renderQueue();
|
|
22307
22452
|
}
|
|
22308
22453
|
|
|
22309
|
-
function dispatchPrompt(text) {
|
|
22454
|
+
function dispatchPrompt(text, images) {
|
|
22455
|
+
var payloadImages = images || [];
|
|
22310
22456
|
var normalized = text.trim().toLowerCase();
|
|
22311
22457
|
if (normalized === "/resume" || normalized === "resume") {
|
|
22312
22458
|
showResumePicker();
|
|
@@ -22322,7 +22468,8 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22322
22468
|
api("POST", isCmd ? "/api/command" : "/api/prompt", {
|
|
22323
22469
|
text: text,
|
|
22324
22470
|
refs: refs,
|
|
22325
|
-
mentions: sessionMentions.map(function (item) { return { kind: "session", id: item.id }; })
|
|
22471
|
+
mentions: sessionMentions.map(function (item) { return { kind: "session", id: item.id }; }),
|
|
22472
|
+
images: payloadImages.map(function (item) { return { name: item.name, mimeType: item.mimeType, data: item.data }; })
|
|
22326
22473
|
}).then(function (res) {
|
|
22327
22474
|
if (!res.ok) {
|
|
22328
22475
|
return readError(res, "Request failed").then(function (msg) { addBlock("alert", msg); });
|
|
@@ -22341,7 +22488,10 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22341
22488
|
if (!steerNow && busy) return;
|
|
22342
22489
|
var next = promptQueue.shift();
|
|
22343
22490
|
renderQueue();
|
|
22344
|
-
if (next)
|
|
22491
|
+
if (next) {
|
|
22492
|
+
if (typeof next === "string") dispatchPrompt(next, []);
|
|
22493
|
+
else dispatchPrompt(next.text || "", next.images || []);
|
|
22494
|
+
}
|
|
22345
22495
|
}
|
|
22346
22496
|
|
|
22347
22497
|
function setAlways(on) {
|
|
@@ -22701,8 +22851,8 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22701
22851
|
var vals = usageHistory.map(function (r) { return r.input + r.output + r.reasoning; });
|
|
22702
22852
|
var max = Math.max.apply(null, vals.concat([1]));
|
|
22703
22853
|
var w = 640, h = 150, gap = 2, bw = Math.max(2, (w - (vals.length - 1) * gap) / vals.length);
|
|
22704
|
-
var rects = vals.map(function (v, i) { var bh = Math.max(2, v / max * 126); var x = i * (bw + gap); return "<rect x=\\"" + x.toFixed(1) + "\\" y=\\"" + (140 - bh).toFixed(1) + "\\" width=\\"" + bw.toFixed(1) + "\\" height=\\"" + bh.toFixed(1) + "\\" rx=\\"1.5\\" fill=\\"
|
|
22705
|
-
chart.innerHTML = "<svg viewBox=\\"0 0 640 150\\" preserveAspectRatio=\\"none\\" aria-label=\\"Token usage by model call\\"><line x1=\\"0\\" y1=\\"140\\" x2=\\"640\\" y2=\\"140\\" stroke=\\"
|
|
22854
|
+
var rects = vals.map(function (v, i) { var bh = Math.max(2, v / max * 126); var x = i * (bw + gap); return "<rect x=\\"" + x.toFixed(1) + "\\" y=\\"" + (140 - bh).toFixed(1) + "\\" width=\\"" + bw.toFixed(1) + "\\" height=\\"" + bh.toFixed(1) + "\\" rx=\\"1.5\\" fill=\\"currentColor\\"><title>" + fmtNum(v) + " tokens</title></rect>"; }).join("");
|
|
22855
|
+
chart.innerHTML = "<svg viewBox=\\"0 0 640 150\\" preserveAspectRatio=\\"none\\" aria-label=\\"Token usage by model call\\"><line x1=\\"0\\" y1=\\"140\\" x2=\\"640\\" y2=\\"140\\" stroke=\\"currentColor\\" opacity=\\".2\\"/>" + rects + "</svg>";
|
|
22706
22856
|
}
|
|
22707
22857
|
}
|
|
22708
22858
|
var phaseRows = [];
|
|
@@ -23292,16 +23442,18 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23292
23442
|
|
|
23293
23443
|
function submitText(raw, steerNow) {
|
|
23294
23444
|
var text = (raw == null ? inputEl.value : raw).trim();
|
|
23295
|
-
|
|
23296
|
-
if (
|
|
23445
|
+
var images = raw == null ? pendingImages.slice() : [];
|
|
23446
|
+
if (raw == null && (text || images.length)) { inputEl.value = ""; autosizeInput(); }
|
|
23447
|
+
if (!text && !images.length) {
|
|
23297
23448
|
if (steerNow) flushQueue(true);
|
|
23298
23449
|
return;
|
|
23299
23450
|
}
|
|
23451
|
+
if (raw == null) { pendingImages = []; renderChips(); }
|
|
23300
23452
|
if (busy && !steerNow) {
|
|
23301
|
-
enqueuePrompt(text);
|
|
23453
|
+
enqueuePrompt(text, images);
|
|
23302
23454
|
return;
|
|
23303
23455
|
}
|
|
23304
|
-
dispatchPrompt(text);
|
|
23456
|
+
dispatchPrompt(text || "Look at the attached image.", images);
|
|
23305
23457
|
}
|
|
23306
23458
|
|
|
23307
23459
|
function decide(decision) {
|
|
@@ -23420,6 +23572,50 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23420
23572
|
chip.addEventListener("click", function () { sessionMentions.splice(i, 1); renderChips(); });
|
|
23421
23573
|
el.appendChild(chip);
|
|
23422
23574
|
});
|
|
23575
|
+
pendingImages.forEach(function (item, i) {
|
|
23576
|
+
var chip = document.createElement("span");
|
|
23577
|
+
chip.className = "chip chip-img";
|
|
23578
|
+
var img = document.createElement("img");
|
|
23579
|
+
img.src = item.preview || ("data:" + item.mimeType + ";base64," + item.data);
|
|
23580
|
+
img.alt = item.name || "image";
|
|
23581
|
+
chip.appendChild(img);
|
|
23582
|
+
var label = document.createElement("span");
|
|
23583
|
+
label.textContent = (item.name || "image") + " \xD7";
|
|
23584
|
+
chip.appendChild(label);
|
|
23585
|
+
chip.addEventListener("click", function () { pendingImages.splice(i, 1); renderChips(); });
|
|
23586
|
+
el.appendChild(chip);
|
|
23587
|
+
});
|
|
23588
|
+
}
|
|
23589
|
+
|
|
23590
|
+
function isImageFile(file) {
|
|
23591
|
+
return file && /^image\\/(png|jpe?g|gif|webp)$/i.test(file.type || "");
|
|
23592
|
+
}
|
|
23593
|
+
|
|
23594
|
+
function addImageFile(file) {
|
|
23595
|
+
if (!isImageFile(file)) return false;
|
|
23596
|
+
if (pendingImages.length >= 8) {
|
|
23597
|
+
addBlock("alert", "You can attach up to 8 images.");
|
|
23598
|
+
return true;
|
|
23599
|
+
}
|
|
23600
|
+
if (file.size > 6 * 1024 * 1024) {
|
|
23601
|
+
addBlock("alert", "Image is too large (6MB max).");
|
|
23602
|
+
return true;
|
|
23603
|
+
}
|
|
23604
|
+
var reader = new FileReader();
|
|
23605
|
+
reader.onload = function () {
|
|
23606
|
+
var dataUrl = String(reader.result || "");
|
|
23607
|
+
var b64 = dataUrl.split(",")[1] || "";
|
|
23608
|
+
if (!b64) return;
|
|
23609
|
+
pendingImages.push({
|
|
23610
|
+
name: file.name || "paste.png",
|
|
23611
|
+
mimeType: file.type || "image/png",
|
|
23612
|
+
data: b64,
|
|
23613
|
+
preview: dataUrl
|
|
23614
|
+
});
|
|
23615
|
+
renderChips();
|
|
23616
|
+
};
|
|
23617
|
+
reader.readAsDataURL(file);
|
|
23618
|
+
return true;
|
|
23423
23619
|
}
|
|
23424
23620
|
|
|
23425
23621
|
function addRef(path) {
|
|
@@ -23749,6 +23945,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23749
23945
|
var files = e.dataTransfer && e.dataTransfer.files;
|
|
23750
23946
|
if (!files) return;
|
|
23751
23947
|
Array.from(files).forEach(function (file) {
|
|
23948
|
+
if (addImageFile(file)) return;
|
|
23752
23949
|
var reader = new FileReader();
|
|
23753
23950
|
reader.onload = function () {
|
|
23754
23951
|
pendingImport = { name: file.name, contents: String(reader.result || "") };
|
|
@@ -23760,6 +23957,26 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23760
23957
|
reader.readAsText(file);
|
|
23761
23958
|
});
|
|
23762
23959
|
});
|
|
23960
|
+
inputEl.addEventListener("paste", function (e) {
|
|
23961
|
+
var clip = e.clipboardData;
|
|
23962
|
+
if (!clip) return;
|
|
23963
|
+
var attached = false;
|
|
23964
|
+
if (clip.items) {
|
|
23965
|
+
for (var i = 0; i < clip.items.length; i++) {
|
|
23966
|
+
var item = clip.items[i];
|
|
23967
|
+
if (item.kind === "file" && String(item.type || "").indexOf("image/") === 0) {
|
|
23968
|
+
var file = item.getAsFile();
|
|
23969
|
+
if (file && addImageFile(file)) attached = true;
|
|
23970
|
+
}
|
|
23971
|
+
}
|
|
23972
|
+
}
|
|
23973
|
+
if (!attached && clip.files) {
|
|
23974
|
+
Array.from(clip.files).forEach(function (file) {
|
|
23975
|
+
if (addImageFile(file)) attached = true;
|
|
23976
|
+
});
|
|
23977
|
+
}
|
|
23978
|
+
if (attached && !(clip.getData("text/plain") || "").trim()) e.preventDefault();
|
|
23979
|
+
});
|
|
23763
23980
|
if (filesBadge) filesBadge.addEventListener("click", function () {
|
|
23764
23981
|
layout.changes = true;
|
|
23765
23982
|
applyLayout();
|
|
@@ -25076,14 +25293,14 @@ async function loadPiTui() {
|
|
|
25076
25293
|
return await import(specifier);
|
|
25077
25294
|
} catch (error) {
|
|
25078
25295
|
const { existsSync: existsSync3 } = await import("node:fs");
|
|
25079
|
-
const { dirname: dirname11, join:
|
|
25296
|
+
const { dirname: dirname11, join: join23 } = await import("node:path");
|
|
25080
25297
|
const { fileURLToPath: fileURLToPath3, pathToFileURL: pathToFileURL3 } = await import("node:url");
|
|
25081
25298
|
const roots = [
|
|
25082
|
-
|
|
25083
|
-
|
|
25299
|
+
join23(dirname11(fileURLToPath3(import.meta.url)), "../../packages/critique-code/.vendor"),
|
|
25300
|
+
join23(dirname11(fileURLToPath3(import.meta.url)), "../../packages/critique-code")
|
|
25084
25301
|
];
|
|
25085
25302
|
for (const root of roots) {
|
|
25086
|
-
const candidate =
|
|
25303
|
+
const candidate = join23(root, "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-tui/dist/index.js");
|
|
25087
25304
|
if (!existsSync3(candidate)) continue;
|
|
25088
25305
|
return await import(pathToFileURL3(candidate).href);
|
|
25089
25306
|
}
|
|
@@ -25235,7 +25452,7 @@ async function createInteractiveSettingsUi(input) {
|
|
|
25235
25452
|
init_zod();
|
|
25236
25453
|
import { spawn as spawn3 } from "node:child_process";
|
|
25237
25454
|
import { accessSync, constants } from "node:fs";
|
|
25238
|
-
import { delimiter as delimiter2, join as
|
|
25455
|
+
import { delimiter as delimiter2, join as join16 } from "node:path";
|
|
25239
25456
|
var CRITIQUE_CLI_MISSING_HINT = "Critique CLI is not on PATH. Install `@critiquedotsh/cli` (binary `critique`) or set CRITIQUE_CLI to that executable. `/critique` and `critique_cli` spawn the sidecar; they do not replace `/review`.";
|
|
25240
25457
|
var TOOL_COMMANDS = [
|
|
25241
25458
|
"review",
|
|
@@ -25499,7 +25716,7 @@ function resolveCritiqueCliBinary(env = process.env) {
|
|
|
25499
25716
|
for (const directory of pathEnv.split(delimiter2)) {
|
|
25500
25717
|
if (!directory) continue;
|
|
25501
25718
|
for (const name of names) {
|
|
25502
|
-
const candidate =
|
|
25719
|
+
const candidate = join16(directory, name);
|
|
25503
25720
|
try {
|
|
25504
25721
|
accessSync(candidate, mode);
|
|
25505
25722
|
return candidate;
|
|
@@ -25735,7 +25952,7 @@ var AUTHOR_PALETTE_ITEMS = [
|
|
|
25735
25952
|
{ value: "/repeat", label: "Repeat", description: "Re-run the last command" },
|
|
25736
25953
|
{ value: "/theme", label: "Theme", description: "Color and compact layout for this TUI" },
|
|
25737
25954
|
{ value: "/alias", label: "Aliases", description: "Bind shortcuts to command chains" },
|
|
25738
|
-
{ value: "/remote", label: "Remote", description: "
|
|
25955
|
+
{ value: "/remote", label: "Remote", description: "Attach critique.sh/code via Critique Remote" },
|
|
25739
25956
|
{ value: "/connect", label: "Connect website", description: "Attach critique.sh/code to this laptop" },
|
|
25740
25957
|
{ value: "/slack", label: "Slack", description: "Attach Slack Socket Mode to this laptop session" },
|
|
25741
25958
|
{ value: "/telegram", label: "Telegram", description: "Attach a Telegram bot to this laptop session" },
|
|
@@ -25786,7 +26003,7 @@ function formatAuthorHelp() {
|
|
|
25786
26003
|
" /context tokens and loaded files",
|
|
25787
26004
|
" /status /logs /cost /doctor",
|
|
25788
26005
|
" /undo /repeat /theme /alias",
|
|
25789
|
-
" /remote
|
|
26006
|
+
" /remote attach critique.sh/code (Critique Remote). /remote lan for Wi-Fi PIN",
|
|
25790
26007
|
" /connect attach critique.sh/code to this laptop (paste the website code)",
|
|
25791
26008
|
" /slack attach Slack Socket Mode; DMs run on this laptop",
|
|
25792
26009
|
" /telegram attach a Telegram bot; chats run on this laptop",
|
|
@@ -25975,6 +26192,7 @@ function parseAuthorCommand(line, aliases = {}) {
|
|
|
25975
26192
|
if (lower.startsWith("/alias ")) return parseAlias(expanded);
|
|
25976
26193
|
if (lower === "/remote" || lower === "remote") return { kind: "remote" };
|
|
25977
26194
|
if (lower === "/remote anywhere" || lower === "/remote --anywhere") return { kind: "remote", anywhere: true };
|
|
26195
|
+
if (lower === "/remote lan" || lower === "/remote --lan") return { kind: "remote", lan: true };
|
|
25978
26196
|
if (lower === "/connect" || lower === "connect" || lower === "/site" || lower === "site") return { kind: "site" };
|
|
25979
26197
|
if (lower.startsWith("/connect ")) return { kind: "site", offerCode: expanded.slice(9).trim() };
|
|
25980
26198
|
if (lower === "/slack" || lower === "slack") return { kind: "slack" };
|
|
@@ -25991,7 +26209,7 @@ function parseAuthorCommand(line, aliases = {}) {
|
|
|
25991
26209
|
// lib/finish/critique-code-web-changes.ts
|
|
25992
26210
|
import { execFileSync } from "node:child_process";
|
|
25993
26211
|
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
25994
|
-
import { readFile as
|
|
26212
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
25995
26213
|
import { dirname as dirname8, isAbsolute as isAbsolute16, relative as relative9, resolve as resolve11 } from "node:path";
|
|
25996
26214
|
var SKIP_TREE_SEGMENTS = /* @__PURE__ */ new Set([".git", "node_modules", ".critique"]);
|
|
25997
26215
|
function git3(root, args) {
|
|
@@ -26154,7 +26372,7 @@ async function workingTreeFilePatch(root, path2) {
|
|
|
26154
26372
|
} catch {
|
|
26155
26373
|
}
|
|
26156
26374
|
try {
|
|
26157
|
-
const contents = await
|
|
26375
|
+
const contents = await readFile18(`${root}/${path2}`, "utf8");
|
|
26158
26376
|
const lines = contents.split("\n");
|
|
26159
26377
|
const body = lines.map((line) => `+${line}`).join("\n");
|
|
26160
26378
|
return {
|
|
@@ -26376,9 +26594,9 @@ function commitMessageFromReview(input) {
|
|
|
26376
26594
|
|
|
26377
26595
|
// lib/finish/critique-code-skills.ts
|
|
26378
26596
|
init_critique_code_runtime_config();
|
|
26379
|
-
import { cp, mkdir as
|
|
26597
|
+
import { cp, mkdir as mkdir13, readdir as readdir2, readFile as readFile19, writeFile as writeFile12 } from "node:fs/promises";
|
|
26380
26598
|
import { homedir as homedir2 } from "node:os";
|
|
26381
|
-
import { isAbsolute as isAbsolute17, join as
|
|
26599
|
+
import { isAbsolute as isAbsolute17, join as join17, relative as relative10, resolve as resolve12, sep as sep10 } from "node:path";
|
|
26382
26600
|
var CRITIQUE_CODE_SKILL_SCHEMA = "critique.code-skill.v1";
|
|
26383
26601
|
var MAX_SKILL_BYTES = 64 * 1024;
|
|
26384
26602
|
var MAX_IMPORTED_SKILLS = 80;
|
|
@@ -26600,16 +26818,16 @@ var PROJECT_SKILL_DIRS = [
|
|
|
26600
26818
|
];
|
|
26601
26819
|
function userSkillDirs(home, userHome) {
|
|
26602
26820
|
return [
|
|
26603
|
-
{ root:
|
|
26604
|
-
{ root:
|
|
26605
|
-
{ root:
|
|
26606
|
-
{ root:
|
|
26607
|
-
{ root:
|
|
26608
|
-
{ root:
|
|
26821
|
+
{ root: join17(home, "skills"), source: "imported" },
|
|
26822
|
+
{ root: join17(userHome, ".claude", "skills"), source: "claude-code" },
|
|
26823
|
+
{ root: join17(userHome, ".codex", "skills"), source: "codex" },
|
|
26824
|
+
{ root: join17(userHome, ".agents", "skills"), source: "agents" },
|
|
26825
|
+
{ root: join17(userHome, ".opencode", "skills"), source: "opencode" },
|
|
26826
|
+
{ root: join17(userHome, ".cursor", "skills"), source: "cursor" }
|
|
26609
26827
|
];
|
|
26610
26828
|
}
|
|
26611
26829
|
function critiqueCodeImportedSkillsPath(home) {
|
|
26612
|
-
return
|
|
26830
|
+
return join17(home, "skills");
|
|
26613
26831
|
}
|
|
26614
26832
|
function skillId(value) {
|
|
26615
26833
|
const id4 = value.trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -26636,7 +26854,7 @@ function parseFrontmatter(markdown) {
|
|
|
26636
26854
|
async function readSkillFile(file, source, origin, fallbackId) {
|
|
26637
26855
|
let markdown;
|
|
26638
26856
|
try {
|
|
26639
|
-
markdown = await
|
|
26857
|
+
markdown = await readFile19(file, "utf8");
|
|
26640
26858
|
} catch {
|
|
26641
26859
|
return void 0;
|
|
26642
26860
|
}
|
|
@@ -26664,7 +26882,7 @@ async function loadSkillsFromRoot(root, source) {
|
|
|
26664
26882
|
}
|
|
26665
26883
|
const skills = [];
|
|
26666
26884
|
for (const entry of entries) {
|
|
26667
|
-
const nested4 =
|
|
26885
|
+
const nested4 = join17(root, entry, "SKILL.md");
|
|
26668
26886
|
const skill = await readSkillFile(nested4, source, nested4, entry);
|
|
26669
26887
|
if (skill) skills.push(skill);
|
|
26670
26888
|
}
|
|
@@ -26714,7 +26932,7 @@ async function discoverCritiqueCodeSkills(input) {
|
|
|
26714
26932
|
}
|
|
26715
26933
|
let imported = 0;
|
|
26716
26934
|
for (const dir of PROJECT_SKILL_DIRS) {
|
|
26717
|
-
const root =
|
|
26935
|
+
const root = join17(cwd, dir.relative);
|
|
26718
26936
|
if (!contained(cwd, root)) continue;
|
|
26719
26937
|
for (const skill of await loadSkillsFromRoot(root, dir.source)) {
|
|
26720
26938
|
if (skill.source !== "builtin" && skill.source !== "imported") {
|
|
@@ -26746,20 +26964,20 @@ function formatCritiqueCodeSkillsList(skills) {
|
|
|
26746
26964
|
`;
|
|
26747
26965
|
}
|
|
26748
26966
|
async function stageCritiqueCodeSkills(input) {
|
|
26749
|
-
const dest =
|
|
26750
|
-
await
|
|
26967
|
+
const dest = join17(input.agent_root, "skills");
|
|
26968
|
+
await mkdir13(dest, { recursive: true });
|
|
26751
26969
|
for (const skill of input.skills) {
|
|
26752
26970
|
const id4 = skillId(skill.id);
|
|
26753
26971
|
if (!id4) continue;
|
|
26754
|
-
const folder =
|
|
26755
|
-
await
|
|
26972
|
+
const folder = join17(dest, id4);
|
|
26973
|
+
await mkdir13(folder, { recursive: true });
|
|
26756
26974
|
const header = `---
|
|
26757
26975
|
name: ${skill.id}
|
|
26758
26976
|
description: ${skill.description.replace(/\n/g, " ").slice(0, 1024)}
|
|
26759
26977
|
---
|
|
26760
26978
|
|
|
26761
26979
|
`;
|
|
26762
|
-
await
|
|
26980
|
+
await writeFile12(join17(folder, "SKILL.md"), `${header}${skill.body.trim()}
|
|
26763
26981
|
`, "utf8");
|
|
26764
26982
|
}
|
|
26765
26983
|
return dest;
|
|
@@ -26768,7 +26986,7 @@ async function importCritiqueCodeSkills(input) {
|
|
|
26768
26986
|
const env = input.env ?? process.env;
|
|
26769
26987
|
const home = critiqueCodeHome(env);
|
|
26770
26988
|
const destRoot = critiqueCodeImportedSkillsPath(home);
|
|
26771
|
-
await
|
|
26989
|
+
await mkdir13(destRoot, { recursive: true });
|
|
26772
26990
|
const discovered = await discoverCritiqueCodeSkills({
|
|
26773
26991
|
cwd: input.cwd,
|
|
26774
26992
|
env,
|
|
@@ -26781,18 +26999,18 @@ async function importCritiqueCodeSkills(input) {
|
|
|
26781
26999
|
skipped.push(skill.id);
|
|
26782
27000
|
continue;
|
|
26783
27001
|
}
|
|
26784
|
-
const folder =
|
|
26785
|
-
await
|
|
27002
|
+
const folder = join17(destRoot, skill.id);
|
|
27003
|
+
await mkdir13(folder, { recursive: true });
|
|
26786
27004
|
if (skill.origin.endsWith(`${sep10}SKILL.md`)) {
|
|
26787
27005
|
try {
|
|
26788
|
-
await cp(skill.origin,
|
|
26789
|
-
imported.push({ ...skill, source: "imported", origin:
|
|
27006
|
+
await cp(skill.origin, join17(folder, "SKILL.md"));
|
|
27007
|
+
imported.push({ ...skill, source: "imported", origin: join17(folder, "SKILL.md") });
|
|
26790
27008
|
continue;
|
|
26791
27009
|
} catch {
|
|
26792
27010
|
}
|
|
26793
27011
|
}
|
|
26794
|
-
await
|
|
26795
|
-
|
|
27012
|
+
await writeFile12(
|
|
27013
|
+
join17(folder, "SKILL.md"),
|
|
26796
27014
|
`---
|
|
26797
27015
|
name: ${skill.id}
|
|
26798
27016
|
description: ${skill.description.replace(/\n/g, " ")}
|
|
@@ -26802,7 +27020,7 @@ ${skill.body.trim()}
|
|
|
26802
27020
|
`,
|
|
26803
27021
|
"utf8"
|
|
26804
27022
|
);
|
|
26805
|
-
imported.push({ ...skill, source: "imported", origin:
|
|
27023
|
+
imported.push({ ...skill, source: "imported", origin: join17(folder, "SKILL.md") });
|
|
26806
27024
|
}
|
|
26807
27025
|
return { home, imported, skipped };
|
|
26808
27026
|
}
|
|
@@ -26811,9 +27029,9 @@ ${skill.body.trim()}
|
|
|
26811
27029
|
import { spawn as spawn4 } from "node:child_process";
|
|
26812
27030
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
26813
27031
|
import { createRequire } from "node:module";
|
|
26814
|
-
import { mkdtemp as mkdtemp3, readFile as
|
|
27032
|
+
import { mkdtemp as mkdtemp3, readFile as readFile20, rm as rm3 } from "node:fs/promises";
|
|
26815
27033
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
26816
|
-
import { dirname as dirname9, join as
|
|
27034
|
+
import { dirname as dirname9, join as join18 } from "node:path";
|
|
26817
27035
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
26818
27036
|
|
|
26819
27037
|
// lib/inference/qwen3-asr.ts
|
|
@@ -26907,8 +27125,8 @@ function resolveBundledFfmpegPath(from = import.meta.url) {
|
|
|
26907
27125
|
try {
|
|
26908
27126
|
let dir = dirname9(fileURLToPath2(from));
|
|
26909
27127
|
for (let i = 0; i < 10; i++) {
|
|
26910
|
-
const harnessPkg =
|
|
26911
|
-
const pkg =
|
|
27128
|
+
const harnessPkg = join18(dir, "packages/critique-code/package.json");
|
|
27129
|
+
const pkg = join18(dir, "package.json");
|
|
26912
27130
|
if (existsSync2(harnessPkg)) bases.push(pathToFileURL2(harnessPkg).href);
|
|
26913
27131
|
if (existsSync2(pkg)) {
|
|
26914
27132
|
try {
|
|
@@ -26945,8 +27163,8 @@ function listVoiceRecorderCandidates(input) {
|
|
|
26945
27163
|
}
|
|
26946
27164
|
async function recordMicrophoneWav(input) {
|
|
26947
27165
|
const run = input.spawn ?? spawn4;
|
|
26948
|
-
const dir = await mkdtemp3(
|
|
26949
|
-
const file =
|
|
27166
|
+
const dir = await mkdtemp3(join18(tmpdir5(), "critique-code-voice-"));
|
|
27167
|
+
const file = join18(dir, "clip.wav");
|
|
26950
27168
|
const stop = input.waitForStop ?? (input.stdin ? () => waitForEnter(input.stdin) : void 0);
|
|
26951
27169
|
if (!stop) {
|
|
26952
27170
|
await rm3(dir, { recursive: true, force: true });
|
|
@@ -26965,7 +27183,7 @@ async function recordMicrophoneWav(input) {
|
|
|
26965
27183
|
settled = true;
|
|
26966
27184
|
clearTimeout(timeout);
|
|
26967
27185
|
try {
|
|
26968
|
-
const wav = await
|
|
27186
|
+
const wav = await readFile20(file);
|
|
26969
27187
|
if (wav.length >= 44) {
|
|
26970
27188
|
resolve14({ wav });
|
|
26971
27189
|
return;
|
|
@@ -27282,7 +27500,7 @@ function createPiAuthorTaskProjectedTool(projection) {
|
|
|
27282
27500
|
init_pi_source_tool();
|
|
27283
27501
|
|
|
27284
27502
|
// lib/finish/critique-code-workspace-memory.ts
|
|
27285
|
-
import { chmod as chmod3, mkdir as
|
|
27503
|
+
import { chmod as chmod3, mkdir as mkdir14, readFile as readFile21, writeFile as writeFile13 } from "node:fs/promises";
|
|
27286
27504
|
import { dirname as dirname10 } from "node:path";
|
|
27287
27505
|
var MAX_MEMORY_RECORDS = 200;
|
|
27288
27506
|
var MAX_MEMORY_VALUE_CHARS = 8192;
|
|
@@ -27346,7 +27564,7 @@ var CritiqueCodeWorkspaceMemory = class {
|
|
|
27346
27564
|
}
|
|
27347
27565
|
async load() {
|
|
27348
27566
|
try {
|
|
27349
|
-
const raw = await
|
|
27567
|
+
const raw = await readFile21(this.#filePath, "utf8");
|
|
27350
27568
|
const parsed = JSON.parse(raw);
|
|
27351
27569
|
this.#records = Array.isArray(parsed.records) ? parsed.records.filter(isMemoryRecord).slice(-MAX_MEMORY_RECORDS) : [];
|
|
27352
27570
|
} catch (error) {
|
|
@@ -27374,8 +27592,8 @@ var CritiqueCodeWorkspaceMemory = class {
|
|
|
27374
27592
|
if (this.#records.length > MAX_MEMORY_RECORDS) {
|
|
27375
27593
|
this.#records = this.#records.slice(-MAX_MEMORY_RECORDS);
|
|
27376
27594
|
}
|
|
27377
|
-
await
|
|
27378
|
-
await
|
|
27595
|
+
await mkdir14(dirname10(this.#filePath), { recursive: true });
|
|
27596
|
+
await writeFile13(this.#filePath, `${JSON.stringify({ records: this.#records })}
|
|
27379
27597
|
`, { mode: 384 });
|
|
27380
27598
|
await chmod3(this.#filePath, 384);
|
|
27381
27599
|
}
|
|
@@ -27397,7 +27615,7 @@ var CritiqueCodeWorkspaceMemory = class {
|
|
|
27397
27615
|
|
|
27398
27616
|
// lib/finish/critique-code-workspace-tool.ts
|
|
27399
27617
|
init_zod();
|
|
27400
|
-
import { readFile as
|
|
27618
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
27401
27619
|
|
|
27402
27620
|
// lib/finish/critique-code-ts-edit.ts
|
|
27403
27621
|
import ts2 from "typescript";
|
|
@@ -27441,7 +27659,7 @@ function renameTsIdentifier(input) {
|
|
|
27441
27659
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
27442
27660
|
import { readFileSync as readFileSync3, readdirSync } from "node:fs";
|
|
27443
27661
|
import { createServer } from "node:net";
|
|
27444
|
-
import { join as
|
|
27662
|
+
import { join as join19 } from "node:path";
|
|
27445
27663
|
var SKIP_DIR_NAMES = /* @__PURE__ */ new Set([".git", "node_modules", ".critique", "dist"]);
|
|
27446
27664
|
var SUBPROCESS_TIMEOUT_MS = 4e3;
|
|
27447
27665
|
var FETCH_TIMEOUT_MS = 8e3;
|
|
@@ -27530,7 +27748,7 @@ function walkWorkspaceFiles(root, pattern, maxHits) {
|
|
|
27530
27748
|
if (hits.length >= maxHits) return;
|
|
27531
27749
|
if (SKIP_DIR_NAMES.has(entry.name)) continue;
|
|
27532
27750
|
const rel = relDir ? `${relDir}/${entry.name}` : entry.name;
|
|
27533
|
-
const abs =
|
|
27751
|
+
const abs = join19(absDir, entry.name);
|
|
27534
27752
|
if (entry.isDirectory()) {
|
|
27535
27753
|
visit(abs, rel);
|
|
27536
27754
|
continue;
|
|
@@ -27581,7 +27799,7 @@ function grepWorkspaceJs(root, query, maxHits) {
|
|
|
27581
27799
|
if (hits.length >= maxHits) break;
|
|
27582
27800
|
let bytes;
|
|
27583
27801
|
try {
|
|
27584
|
-
bytes = readFileSync3(
|
|
27802
|
+
bytes = readFileSync3(join19(root, rel));
|
|
27585
27803
|
} catch {
|
|
27586
27804
|
continue;
|
|
27587
27805
|
}
|
|
@@ -27893,19 +28111,19 @@ var PiWorkspaceToolProjection = class {
|
|
|
27893
28111
|
return { hits: grepWorkspaceIntel(this.#root, input.query) };
|
|
27894
28112
|
case "diff": {
|
|
27895
28113
|
if (!input.path) throw new Error("diff requires path.");
|
|
27896
|
-
const current = await
|
|
28114
|
+
const current = await readFile22(safeRepoPath(this.#root, input.path), "utf8");
|
|
27897
28115
|
const previous = input.before ?? "";
|
|
27898
28116
|
return { path: input.path, patch: unifiedDiff(previous, input.after ?? current, input.path) };
|
|
27899
28117
|
}
|
|
27900
28118
|
case "parse_config": {
|
|
27901
28119
|
if (!input.path) throw new Error("parse_config requires path.");
|
|
27902
|
-
const text = await
|
|
28120
|
+
const text = await readFile22(safeRepoPath(this.#root, input.path), "utf8");
|
|
27903
28121
|
return parseStructuredConfig(text, input.kind ?? "auto");
|
|
27904
28122
|
}
|
|
27905
28123
|
case "env_keys": {
|
|
27906
28124
|
const rel = input.path ?? ".env";
|
|
27907
28125
|
try {
|
|
27908
|
-
const text = await
|
|
28126
|
+
const text = await readFile22(safeRepoPath(this.#root, rel), "utf8");
|
|
27909
28127
|
return { path: rel, keys: parseDotenvKeys(text), limitation: "Values are never returned." };
|
|
27910
28128
|
} catch {
|
|
27911
28129
|
return { path: rel, keys: [], limitation: "File missing. Values are never returned." };
|
|
@@ -27924,7 +28142,7 @@ var PiWorkspaceToolProjection = class {
|
|
|
27924
28142
|
return { records: this.#memory.recall(input.query ?? input.key ?? "") };
|
|
27925
28143
|
case "rename_ts": {
|
|
27926
28144
|
if (!input.path || !input.from || !input.to) throw new Error("rename_ts requires path, from, and to.");
|
|
27927
|
-
const source = await
|
|
28145
|
+
const source = await readFile22(safeRepoPath(this.#root, input.path), "utf8");
|
|
27928
28146
|
const renamed = renameTsIdentifier({ source, fileName: input.path, from: input.from, to: input.to });
|
|
27929
28147
|
return {
|
|
27930
28148
|
...renamed,
|
|
@@ -28139,7 +28357,7 @@ function wrapAuthorWrite(inner, onWrite, workspaceRoot) {
|
|
|
28139
28357
|
let previous = null;
|
|
28140
28358
|
if (path2) {
|
|
28141
28359
|
try {
|
|
28142
|
-
previous = await
|
|
28360
|
+
previous = await readFile23(join20(workspaceRoot, path2), "utf8");
|
|
28143
28361
|
} catch {
|
|
28144
28362
|
previous = null;
|
|
28145
28363
|
}
|
|
@@ -28158,7 +28376,7 @@ function liveSourceState(state) {
|
|
|
28158
28376
|
}
|
|
28159
28377
|
async function loadReleasedFile(repositoryRoot, name, maxChars) {
|
|
28160
28378
|
try {
|
|
28161
|
-
const text = (await
|
|
28379
|
+
const text = (await readFile23(join20(repositoryRoot, name), "utf8")).trim();
|
|
28162
28380
|
if (!text) return void 0;
|
|
28163
28381
|
const release = await patternSecretEgress().release({ kind: "model_prompt", content: text.slice(0, maxChars) });
|
|
28164
28382
|
return release.content;
|
|
@@ -28240,14 +28458,14 @@ async function runLocalCritiqueCodeAuthor(input) {
|
|
|
28240
28458
|
const storeRoot = input.store_root ?? defaultCritiqueCodeStoreRoot(repositoryRoot);
|
|
28241
28459
|
const sessionOps = new FileSessionOpsStore(storeRoot);
|
|
28242
28460
|
await sessionOps.load();
|
|
28243
|
-
const workspaceMemory = new CritiqueCodeWorkspaceMemory(
|
|
28461
|
+
const workspaceMemory = new CritiqueCodeWorkspaceMemory(join20(storeRoot, "workspace-memory.json"));
|
|
28244
28462
|
await workspaceMemory.load();
|
|
28245
|
-
const agentRoot = input.agent_root ??
|
|
28463
|
+
const agentRoot = input.agent_root ?? join20(tmpdir6(), "critique-code-pi-agent");
|
|
28246
28464
|
if (!isAbsolute19(agentRoot)) {
|
|
28247
28465
|
reader.close();
|
|
28248
28466
|
return { kind: "kernel_required", limitation: "Pi agent root must be an absolute controller-owned directory." };
|
|
28249
28467
|
}
|
|
28250
|
-
if (!input.agent_root) await
|
|
28468
|
+
if (!input.agent_root) await mkdir15(agentRoot, { recursive: true });
|
|
28251
28469
|
const conversationIdSeed = `pi_${createHash38("sha256").update(repositoryRoot).digest("hex").slice(0, 24)}`;
|
|
28252
28470
|
const review = input.review ?? runLocalCritiqueCodeReview;
|
|
28253
28471
|
const checkpoints = new FileReviewCheckpointStore(storeRoot);
|
|
@@ -28689,7 +28907,7 @@ ${prior}`.trim();
|
|
|
28689
28907
|
emitReviewController({ reviewing: false });
|
|
28690
28908
|
}
|
|
28691
28909
|
};
|
|
28692
|
-
const promptAuthor = async (prompt) => {
|
|
28910
|
+
const promptAuthor = async (prompt, images) => {
|
|
28693
28911
|
await ensureSession();
|
|
28694
28912
|
noteWithheld(prompt);
|
|
28695
28913
|
reader.pause();
|
|
@@ -28707,7 +28925,8 @@ ${prior}`.trim();
|
|
|
28707
28925
|
const turn = await authors.prompt({
|
|
28708
28926
|
conversation_id: conversationId2,
|
|
28709
28927
|
prompt: outbound,
|
|
28710
|
-
timeout_ms: timeoutMs
|
|
28928
|
+
timeout_ms: timeoutMs,
|
|
28929
|
+
...images && images.length > 0 ? { images } : {}
|
|
28711
28930
|
});
|
|
28712
28931
|
await sessionOps.recordCost({
|
|
28713
28932
|
at: now().toISOString(),
|
|
@@ -28760,10 +28979,17 @@ ${prior}`.trim();
|
|
|
28760
28979
|
ensureStarted(input.intent.trim());
|
|
28761
28980
|
}
|
|
28762
28981
|
for (; ; ) {
|
|
28763
|
-
const
|
|
28764
|
-
if (
|
|
28982
|
+
const lineRaw = await takeLine();
|
|
28983
|
+
if (lineRaw === void 0) break;
|
|
28984
|
+
const unpacked = unwrapPromptImagePaths(lineRaw);
|
|
28985
|
+
const line = unpacked.text;
|
|
28986
|
+
const packedImages = unpacked.paths.length > 0 ? (await loadPromptImagesFromPaths(unpacked.paths)).map((image) => ({
|
|
28987
|
+
type: "image",
|
|
28988
|
+
data: image.data,
|
|
28989
|
+
mimeType: image.mimeType
|
|
28990
|
+
})) : [];
|
|
28765
28991
|
let command = authorCommand(line, sessionOps.state().aliases, skills);
|
|
28766
|
-
if (!command && !line.trim()) continue;
|
|
28992
|
+
if (!command && !line.trim() && packedImages.length === 0) continue;
|
|
28767
28993
|
if (command && command.kind !== "repeat" && command.kind !== "palette" && command.kind !== "help") {
|
|
28768
28994
|
await sessionOps.setLastCommand(line.trim());
|
|
28769
28995
|
}
|
|
@@ -28812,14 +29038,14 @@ ${prior}`.trim();
|
|
|
28812
29038
|
}
|
|
28813
29039
|
if (command?.kind === "remote" || command?.kind === "slack" || command?.kind === "telegram" || command?.kind === "site") {
|
|
28814
29040
|
if (!input.on_surface) {
|
|
28815
|
-
say(command.kind === "remote" ? "
|
|
29041
|
+
say(command.kind === "remote" ? "Critique Remote is `critique-code remote` after `critique-code login`. Leave that process running. Use `--lan` for same-Wi-Fi PIN pairing.\n" : command.kind === "site" ? "Website connect is `critique-code connect [CODE]` after critique-code login. Kernel stays on this laptop.\n" : `Connect ${command.kind} with \`critique-code ${command.kind}\` in this repo. The kernel stays on this laptop.
|
|
28816
29042
|
`);
|
|
28817
29043
|
continue;
|
|
28818
29044
|
}
|
|
28819
29045
|
try {
|
|
28820
29046
|
await input.on_surface(
|
|
28821
29047
|
command.kind,
|
|
28822
|
-
command.kind === "remote" ? { anywhere: command.anywhere } : command.kind === "site" ? { offerCode: command.offerCode } : {}
|
|
29048
|
+
command.kind === "remote" ? { anywhere: command.anywhere, lan: command.lan } : command.kind === "site" ? { offerCode: command.offerCode } : {}
|
|
28823
29049
|
);
|
|
28824
29050
|
} catch (error) {
|
|
28825
29051
|
say(`${error instanceof Error ? error.message : String(error)}
|
|
@@ -28870,7 +29096,7 @@ ${prior}`.trim();
|
|
|
28870
29096
|
}
|
|
28871
29097
|
}
|
|
28872
29098
|
if (thread.action === "fork") {
|
|
28873
|
-
const id5 =
|
|
29099
|
+
const id5 = randomBytes2(6).toString("hex");
|
|
28874
29100
|
const briefing = withheld.trim();
|
|
28875
29101
|
const from = activeThread;
|
|
28876
29102
|
switchThread(id5, true);
|
|
@@ -28890,7 +29116,7 @@ ${briefing}
|
|
|
28890
29116
|
`);
|
|
28891
29117
|
continue;
|
|
28892
29118
|
}
|
|
28893
|
-
const id4 = thread.id?.trim() ||
|
|
29119
|
+
const id4 = thread.id?.trim() || randomBytes2(6).toString("hex");
|
|
28894
29120
|
switchThread(id4, thread.action === "new");
|
|
28895
29121
|
await sessionOps.touchSession({
|
|
28896
29122
|
id: id4,
|
|
@@ -28984,7 +29210,7 @@ ${briefing}
|
|
|
28984
29210
|
`);
|
|
28985
29211
|
continue;
|
|
28986
29212
|
}
|
|
28987
|
-
const id4 =
|
|
29213
|
+
const id4 = randomBytes2(4).toString("hex");
|
|
28988
29214
|
await sessionOps.addSnapshot({
|
|
28989
29215
|
id: id4,
|
|
28990
29216
|
label: command.label?.trim() || `checkpoint ${id4}`,
|
|
@@ -29050,10 +29276,10 @@ ${briefing}
|
|
|
29050
29276
|
const html = command.format === "html" ? `<pre>${markdown.replaceAll("&", "&").replaceAll("<", "<")}</pre>
|
|
29051
29277
|
` : markdown;
|
|
29052
29278
|
const name = `session-${activeThread}.${command.format === "html" ? "html" : "md"}`;
|
|
29053
|
-
const directory =
|
|
29054
|
-
await
|
|
29055
|
-
const target =
|
|
29056
|
-
await
|
|
29279
|
+
const directory = join20(storeRoot, "exports");
|
|
29280
|
+
await mkdir15(directory, { recursive: true, mode: 448 });
|
|
29281
|
+
const target = join20(directory, name);
|
|
29282
|
+
await writeFile14(target, html, { mode: 384 });
|
|
29057
29283
|
say(`Exported ${target}
|
|
29058
29284
|
`);
|
|
29059
29285
|
continue;
|
|
@@ -29405,9 +29631,9 @@ ${current.map((path3) => `- ${path3}`).join("\n")}
|
|
|
29405
29631
|
say("Nothing to undo. /rollback restores a full checkpoint.\n");
|
|
29406
29632
|
continue;
|
|
29407
29633
|
}
|
|
29408
|
-
const target =
|
|
29634
|
+
const target = join20(repositoryRoot, entry.path);
|
|
29409
29635
|
if (entry.previous === null) await unlink4(target).catch(() => void 0);
|
|
29410
|
-
else await
|
|
29636
|
+
else await writeFile14(target, entry.previous);
|
|
29411
29637
|
say(`Undid ${entry.path}.
|
|
29412
29638
|
`);
|
|
29413
29639
|
continue;
|
|
@@ -29543,8 +29769,8 @@ ${current.map((path3) => `- ${path3}`).join("\n")}
|
|
|
29543
29769
|
if (voiceMode) listenNow = true;
|
|
29544
29770
|
continue;
|
|
29545
29771
|
}
|
|
29546
|
-
ensureStarted(line.trim());
|
|
29547
|
-
await promptAuthor(line);
|
|
29772
|
+
ensureStarted(line.trim() || "Look at the attached image.");
|
|
29773
|
+
await promptAuthor(line.trim() || "Look at the attached image.", packedImages.length > 0 ? packedImages : void 0);
|
|
29548
29774
|
if (voiceMode) listenNow = true;
|
|
29549
29775
|
}
|
|
29550
29776
|
} finally {
|
|
@@ -29570,10 +29796,10 @@ ${current.map((path3) => `- ${path3}`).join("\n")}
|
|
|
29570
29796
|
|
|
29571
29797
|
// lib/finish/critique-code-web-server.ts
|
|
29572
29798
|
init_change_capsule();
|
|
29573
|
-
import { randomBytes as
|
|
29799
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
29574
29800
|
import { createServer as createServer2 } from "node:http";
|
|
29575
|
-
import { mkdir as
|
|
29576
|
-
import { basename as basename4, join as
|
|
29801
|
+
import { mkdir as mkdir17, readFile as readFile25, writeFile as writeFile16 } from "node:fs/promises";
|
|
29802
|
+
import { basename as basename4, join as join22 } from "node:path";
|
|
29577
29803
|
import { execFileSync as execFileSync3, spawn as spawn7 } from "node:child_process";
|
|
29578
29804
|
|
|
29579
29805
|
// lib/finish/critique-code-line-hub.ts
|
|
@@ -29787,23 +30013,39 @@ function originAllowed(input) {
|
|
|
29787
30013
|
return parsed.host.toLowerCase() === host;
|
|
29788
30014
|
}
|
|
29789
30015
|
function formatRemoteBanner(input) {
|
|
29790
|
-
const
|
|
29791
|
-
|
|
29792
|
-
|
|
29793
|
-
|
|
29794
|
-
|
|
29795
|
-
|
|
29796
|
-
|
|
29797
|
-
|
|
29798
|
-
|
|
29799
|
-
|
|
29800
|
-
|
|
29801
|
-
|
|
29802
|
-
|
|
29803
|
-
|
|
29804
|
-
|
|
29805
|
-
|
|
29806
|
-
|
|
30016
|
+
const lines = [`CritiqueCode Remote \xB7 ${input.repository_name}`];
|
|
30017
|
+
if (input.cloud_url) {
|
|
30018
|
+
lines.push(
|
|
30019
|
+
"\u25CF Connected to Critique Remote",
|
|
30020
|
+
"Open from any device:",
|
|
30021
|
+
` ${input.cloud_url}`,
|
|
30022
|
+
"Repository and commands remain on this laptop.",
|
|
30023
|
+
"Closing CritiqueCode disconnects remote access."
|
|
30024
|
+
);
|
|
30025
|
+
} else {
|
|
30026
|
+
lines.push("This laptop is the agent. Phone and portals are remotes.");
|
|
30027
|
+
}
|
|
30028
|
+
lines.push(`Local:
|
|
30029
|
+
${input.urls.loopback}`);
|
|
30030
|
+
if (input.pin_display) {
|
|
30031
|
+
lines.push(`Pairing PIN ${input.pin_display}`);
|
|
30032
|
+
if (input.urls.lan.length > 0) {
|
|
30033
|
+
lines.push(`On this Wi-Fi
|
|
30034
|
+
${input.urls.lan.join("\n ")}`);
|
|
30035
|
+
}
|
|
30036
|
+
}
|
|
30037
|
+
if (input.urls.tunnel) {
|
|
30038
|
+
lines.push(`Tunnel URL:
|
|
30039
|
+
${input.urls.tunnel}`);
|
|
30040
|
+
}
|
|
30041
|
+
if (input.portals && input.portals.length > 0) {
|
|
30042
|
+
lines.push(`Portals: ${input.portals.join(", ")}. DM the bot from your phone.`);
|
|
30043
|
+
}
|
|
30044
|
+
if (!input.cloud_url && !input.urls.tunnel) {
|
|
30045
|
+
lines.push("Off-Wi-Fi: run `critique-code remote` after `critique-code login`, or pass --anywhere.");
|
|
30046
|
+
}
|
|
30047
|
+
lines.push("Leave this process running. Sleep or closing the terminal drops remotes.", "");
|
|
30048
|
+
return lines.join("\n");
|
|
29807
30049
|
}
|
|
29808
30050
|
function withToken(url, token) {
|
|
29809
30051
|
const parsed = new URL(url);
|
|
@@ -29885,8 +30127,8 @@ function spawnTunnel(command, args) {
|
|
|
29885
30127
|
|
|
29886
30128
|
// lib/finish/critique-code-portals.ts
|
|
29887
30129
|
init_critique_code_runtime_config();
|
|
29888
|
-
import { mkdir as
|
|
29889
|
-
import { join as
|
|
30130
|
+
import { mkdir as mkdir16, readFile as readFile24, writeFile as writeFile15 } from "node:fs/promises";
|
|
30131
|
+
import { join as join21 } from "node:path";
|
|
29890
30132
|
var CRITIQUE_CODE_PORTALS_SCHEMA = "critique.code-portals.v1";
|
|
29891
30133
|
function isRecord2(value) {
|
|
29892
30134
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -29951,7 +30193,7 @@ async function loadCritiqueCodePortals(env = process.env) {
|
|
|
29951
30193
|
const fromEnv = portalsFromEnv(env);
|
|
29952
30194
|
const home = critiqueCodeHome(env);
|
|
29953
30195
|
try {
|
|
29954
|
-
const raw = JSON.parse(await
|
|
30196
|
+
const raw = JSON.parse(await readFile24(join21(home, "portals.json"), "utf8"));
|
|
29955
30197
|
const stored = parseStoredPortals(raw);
|
|
29956
30198
|
return {
|
|
29957
30199
|
schema_version: CRITIQUE_CODE_PORTALS_SCHEMA,
|
|
@@ -30288,27 +30530,31 @@ async function startCritiqueCodeSiteRelay(input) {
|
|
|
30288
30530
|
repository: input.repository?.trim() || basename3(input.cwd),
|
|
30289
30531
|
cwd: input.cwd
|
|
30290
30532
|
};
|
|
30291
|
-
const claimed =
|
|
30292
|
-
|
|
30293
|
-
...
|
|
30294
|
-
})
|
|
30533
|
+
const claimed = await postJson(fetchImpl, `${origin}/api/new/v1/code/relay/sessions`, headers, {
|
|
30534
|
+
...machine,
|
|
30535
|
+
...input.offerCode ? { code: input.offerCode } : {}
|
|
30536
|
+
});
|
|
30295
30537
|
if (!claimed.ok) {
|
|
30296
30538
|
return { limitation: claimed.error || "critique.sh did not accept this PC." };
|
|
30297
30539
|
}
|
|
30298
|
-
const agentId = String(claimed.body.agentId ?? "");
|
|
30540
|
+
const agentId = String(claimed.body.id ?? claimed.body.agentId ?? "");
|
|
30299
30541
|
const agentToken = String(claimed.body.agentToken ?? "");
|
|
30542
|
+
const browserUrl = String(claimed.body.browser_url ?? `${origin}/code`);
|
|
30300
30543
|
if (!agentId || !agentToken) {
|
|
30301
30544
|
return { limitation: "critique.sh did not return a machine token." };
|
|
30302
30545
|
}
|
|
30303
|
-
input.note?.(`
|
|
30546
|
+
input.note?.(`Connected to Critique Remote. Open ${browserUrl} \xB7 ${machine.hostname} \xB7 ${machine.repository}. Kernel stays on this laptop.`);
|
|
30304
30547
|
const abort = new AbortController();
|
|
30548
|
+
const baseInterval = input.intervalMs ?? 800;
|
|
30549
|
+
const maxInterval = input.maxIntervalMs ?? 3e4;
|
|
30305
30550
|
const loop = (async () => {
|
|
30306
30551
|
const sleep = input.sleep ?? defaultSleep2;
|
|
30552
|
+
let delay = baseInterval;
|
|
30307
30553
|
while (!abort.signal.aborted) {
|
|
30308
30554
|
const events = input.takeEvents().map((event) => ({ ...event }));
|
|
30309
30555
|
const synced = await postJson(
|
|
30310
30556
|
fetchImpl,
|
|
30311
|
-
`${origin}/api/new/v1/code/
|
|
30557
|
+
`${origin}/api/new/v1/code/relay/agent/${agentId}`,
|
|
30312
30558
|
{
|
|
30313
30559
|
authorization: `Bearer ${agentToken}`,
|
|
30314
30560
|
"content-type": "application/json"
|
|
@@ -30319,17 +30565,21 @@ async function startCritiqueCodeSiteRelay(input) {
|
|
|
30319
30565
|
}
|
|
30320
30566
|
);
|
|
30321
30567
|
if (synced.ok && Array.isArray(synced.body.commands)) {
|
|
30568
|
+
delay = baseInterval;
|
|
30322
30569
|
for (const command of synced.body.commands) {
|
|
30323
30570
|
applySiteCommand(input.host, command);
|
|
30324
30571
|
}
|
|
30572
|
+
} else {
|
|
30573
|
+
delay = Math.min(delay * 2, maxInterval);
|
|
30325
30574
|
}
|
|
30326
|
-
await sleep(
|
|
30575
|
+
await sleep(delay);
|
|
30327
30576
|
}
|
|
30328
30577
|
})();
|
|
30329
30578
|
void loop.catch(() => void 0);
|
|
30330
30579
|
return {
|
|
30331
30580
|
agentId,
|
|
30332
30581
|
origin,
|
|
30582
|
+
url: browserUrl,
|
|
30333
30583
|
async close() {
|
|
30334
30584
|
abort.abort();
|
|
30335
30585
|
}
|
|
@@ -30771,7 +31021,7 @@ async function startCritiqueCodeWebServer(input) {
|
|
|
30771
31021
|
return { kind: "kernel_required", limitation: error instanceof Error ? error.message : String(error) };
|
|
30772
31022
|
}
|
|
30773
31023
|
const repositoryRoot = await findRepositoryRoot(input.cwd);
|
|
30774
|
-
const token =
|
|
31024
|
+
const token = randomBytes3(18).toString("base64url");
|
|
30775
31025
|
const hub = new CritiqueCodeLineHub();
|
|
30776
31026
|
const pushLine = (line) => input.attach?.push(line) ?? hub.push(line);
|
|
30777
31027
|
const clients = /* @__PURE__ */ new Set();
|
|
@@ -30800,16 +31050,16 @@ async function startCritiqueCodeWebServer(input) {
|
|
|
30800
31050
|
let reviewModels = [...initialReviewModels];
|
|
30801
31051
|
let pendingExec;
|
|
30802
31052
|
const storeRoot = input.store_root ?? defaultCritiqueCodeStoreRoot(repositoryRoot);
|
|
30803
|
-
const chatsPath =
|
|
31053
|
+
const chatsPath = join22(storeRoot, "web-chats.json");
|
|
30804
31054
|
let chats = [{
|
|
30805
|
-
id:
|
|
31055
|
+
id: randomBytes3(6).toString("hex"),
|
|
30806
31056
|
title: "New session",
|
|
30807
31057
|
created_at: (input.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
|
|
30808
31058
|
events: []
|
|
30809
31059
|
}];
|
|
30810
31060
|
let activeId = chats[0].id;
|
|
30811
31061
|
try {
|
|
30812
|
-
const raw = JSON.parse(await
|
|
31062
|
+
const raw = JSON.parse(await readFile25(chatsPath, "utf8"));
|
|
30813
31063
|
if (Array.isArray(raw.chats) && raw.chats.length > 0) {
|
|
30814
31064
|
chats = raw.chats.map((chat) => ({
|
|
30815
31065
|
id: String(chat.id),
|
|
@@ -30824,7 +31074,7 @@ async function startCritiqueCodeWebServer(input) {
|
|
|
30824
31074
|
const sessionSummaries = () => chats.map((chat) => ({ id: chat.id, title: chat.title, created_at: chat.created_at }));
|
|
30825
31075
|
const activeChat = () => chats.find((chat) => chat.id === activeId) ?? chats[0];
|
|
30826
31076
|
const persistChats = () => {
|
|
30827
|
-
void
|
|
31077
|
+
void mkdir17(storeRoot, { recursive: true, mode: 448 }).then(() => writeFile16(
|
|
30828
31078
|
chatsPath,
|
|
30829
31079
|
`${JSON.stringify({ active_id: activeId, chats }, null, 2)}
|
|
30830
31080
|
`,
|
|
@@ -31012,7 +31262,7 @@ data: ${JSON.stringify(stamped)}
|
|
|
31012
31262
|
return "approve";
|
|
31013
31263
|
}
|
|
31014
31264
|
return new Promise((resolve14) => {
|
|
31015
|
-
const id4 =
|
|
31265
|
+
const id4 = randomBytes3(9).toString("hex");
|
|
31016
31266
|
const pending = { id: id4, purpose: request.purpose, preview: request.preview, resolve: resolve14 };
|
|
31017
31267
|
execs.set(id4, pending);
|
|
31018
31268
|
pendingExec = { id: id4, purpose: request.purpose, preview: request.preview };
|
|
@@ -31260,7 +31510,7 @@ exit ${code2 ?? "killed"}
|
|
|
31260
31510
|
}
|
|
31261
31511
|
if (req.method === "POST" && path2 === "/api/sessions") {
|
|
31262
31512
|
const chat = {
|
|
31263
|
-
id:
|
|
31513
|
+
id: randomBytes3(6).toString("hex"),
|
|
31264
31514
|
title: "New session",
|
|
31265
31515
|
created_at: (input.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
|
|
31266
31516
|
events: []
|
|
@@ -31276,7 +31526,7 @@ exit ${code2 ?? "killed"}
|
|
|
31276
31526
|
if (req.method === "POST" && path2 === "/api/sessions/fork") {
|
|
31277
31527
|
const source = activeChat();
|
|
31278
31528
|
const chat = {
|
|
31279
|
-
id:
|
|
31529
|
+
id: randomBytes3(6).toString("hex"),
|
|
31280
31530
|
title: `${source.title === "New session" ? "Fork" : source.title} \xB7 fork`,
|
|
31281
31531
|
created_at: (input.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
|
|
31282
31532
|
events: source.events.map((event) => ({ ...event }))
|
|
@@ -31431,7 +31681,8 @@ exit ${code2 ?? "killed"}
|
|
|
31431
31681
|
}
|
|
31432
31682
|
if (req.method === "POST" && (path2 === "/api/prompt" || path2 === "/api/command")) {
|
|
31433
31683
|
const body = await readJson(req);
|
|
31434
|
-
const
|
|
31684
|
+
const images = parseWebPromptImages(body.images);
|
|
31685
|
+
const text = String(body.text ?? body.prompt ?? "").trim() || (images.length > 0 ? "Look at the attached image." : "");
|
|
31435
31686
|
if (!text) {
|
|
31436
31687
|
send(res, 400, { error: "text required" });
|
|
31437
31688
|
return;
|
|
@@ -31485,7 +31736,12 @@ ${extras.join("\n\n")}` : text);
|
|
|
31485
31736
|
nameActiveChat(text);
|
|
31486
31737
|
emitGate();
|
|
31487
31738
|
}
|
|
31488
|
-
const queued = pushLine(
|
|
31739
|
+
const queued = pushLine(
|
|
31740
|
+
images.length > 0 && !text.startsWith("/") ? wrapPromptWithImagePaths(
|
|
31741
|
+
outbound,
|
|
31742
|
+
await writeWebPromptImages({ home: critiqueCodeHome(env), images })
|
|
31743
|
+
) : outbound
|
|
31744
|
+
);
|
|
31489
31745
|
send(res, queued ? 202 : 409, { ok: queued });
|
|
31490
31746
|
return;
|
|
31491
31747
|
}
|
|
@@ -31856,15 +32112,16 @@ ${extras.join("\n\n")}` : text);
|
|
|
31856
32112
|
else siteRelay = startedSite;
|
|
31857
32113
|
}
|
|
31858
32114
|
}
|
|
31859
|
-
if (access3 === "pair") {
|
|
32115
|
+
if (access3 === "pair" || siteRelay) {
|
|
31860
32116
|
input.stderr.write(formatRemoteBanner({
|
|
31861
32117
|
repository_name: basename4(repositoryRoot),
|
|
31862
|
-
pin_display: pairing
|
|
32118
|
+
...pairing ? { pin_display: pairing.pin_display } : {},
|
|
31863
32119
|
urls: {
|
|
31864
32120
|
loopback: urls.loopback,
|
|
31865
32121
|
lan: urls.lan,
|
|
31866
32122
|
...urls.tunnel ? { tunnel: urls.tunnel } : {}
|
|
31867
32123
|
},
|
|
32124
|
+
...siteRelay ? { cloud_url: siteRelay.url } : {},
|
|
31868
32125
|
portals: connectedPortals
|
|
31869
32126
|
}));
|
|
31870
32127
|
} else {
|
|
@@ -32009,7 +32266,7 @@ Loopback only. The author session stays in this process.
|
|
|
32009
32266
|
...urls.lan.length > 0 ? { lan_urls: urls.lan } : {},
|
|
32010
32267
|
...urls.tunnel ? { tunnel_url: urls.tunnel } : {},
|
|
32011
32268
|
...connectedPortals.length > 0 ? { portals: connectedPortals } : {},
|
|
32012
|
-
...siteRelay ? { site: { agentId: siteRelay.agentId, origin: siteRelay.origin } } : {},
|
|
32269
|
+
...siteRelay ? { site: { agentId: siteRelay.agentId, origin: siteRelay.origin, url: siteRelay.url } } : {},
|
|
32013
32270
|
async close() {
|
|
32014
32271
|
hub.close();
|
|
32015
32272
|
for (const adapter of portalAdapters) await adapter.stop().catch(() => void 0);
|
|
@@ -32050,7 +32307,7 @@ Usage:
|
|
|
32050
32307
|
pnpm --filter @critiquedotsh/harness start
|
|
32051
32308
|
critique-code | critique-code chat [--intent <text>] [--models provider/model,...] [--cwd <dir>] [--store <dir>] [--voice] [--json]
|
|
32052
32309
|
critique-code web [--port <n>] [--cwd <dir>] [--store <dir>] [--models ...]
|
|
32053
|
-
critique-code remote [--
|
|
32310
|
+
critique-code remote [--lan] [--anywhere] [--slack] [--telegram] [--port <n>] [--cwd <dir>] [--store <dir>] [--models ...]
|
|
32054
32311
|
critique-code connect [CODE] [--port <n>] [--cwd <dir>]
|
|
32055
32312
|
critique-code slack [--port <n>] [--cwd <dir>]
|
|
32056
32313
|
critique-code telegram [--port <n>] [--cwd <dir>]
|
|
@@ -32078,7 +32335,7 @@ Interactive author commands:
|
|
|
32078
32335
|
/watch on Review on file save
|
|
32079
32336
|
/repair Verified repair of promoted findings (not auto-applied chatter)
|
|
32080
32337
|
/ship Review, then end if the controller allows
|
|
32081
|
-
/remote
|
|
32338
|
+
/remote Attach critique.sh/code to this laptop (Critique Remote)
|
|
32082
32339
|
/connect [CODE] Attach critique.sh/code to this laptop
|
|
32083
32340
|
/slack Attach Slack Socket Mode to this session
|
|
32084
32341
|
/telegram Attach a Telegram bot to this session
|
|
@@ -32092,7 +32349,7 @@ Interactive author commands:
|
|
|
32092
32349
|
|
|
32093
32350
|
Interactive TTY author sessions keep stdout quiet; pass --json for the session envelope.
|
|
32094
32351
|
\`critique-code web\` serves a loopback browser UI on 127.0.0.1. The author kernel still runs in this process.
|
|
32095
|
-
\`critique-code remote\`
|
|
32352
|
+
\`critique-code remote\` opens Critique Remote: this laptop stays the agent, critique.sh/code is the remote. Needs \`critique-code login\`. Use --lan for same-Wi-Fi PIN pairing, --anywhere for your cloudflared/ngrok.
|
|
32096
32353
|
\`critique-code connect [CODE]\` registers this PC on critique.sh/code. The website is a remote; the kernel stays here.
|
|
32097
32354
|
\`critique-code slack\` / \`critique-code telegram\` open outbound bots so you can DM the agent from those apps. The kernel stays here.
|
|
32098
32355
|
Other commands print JSON on stdout. Live chrome goes to stderr.
|
|
@@ -32176,6 +32433,8 @@ function parseInvocation(argv) {
|
|
|
32176
32433
|
repair: { type: "string" },
|
|
32177
32434
|
port: { type: "string" },
|
|
32178
32435
|
anywhere: { type: "boolean" },
|
|
32436
|
+
lan: { type: "boolean" },
|
|
32437
|
+
cloud: { type: "boolean" },
|
|
32179
32438
|
slack: { type: "boolean" },
|
|
32180
32439
|
telegram: { type: "boolean" },
|
|
32181
32440
|
pair: { type: "boolean" },
|
|
@@ -32314,9 +32573,11 @@ function parseInvocation(argv) {
|
|
|
32314
32573
|
const portals = [];
|
|
32315
32574
|
if (command === "slack" || parsed.values.slack) portals.push("slack");
|
|
32316
32575
|
if (command === "telegram" || parsed.values.telegram) portals.push("telegram");
|
|
32317
|
-
const
|
|
32576
|
+
const lan = Boolean(parsed.values.lan || parsed.values.pair);
|
|
32577
|
+
const access3 = lan ? "pair" : "loopback";
|
|
32318
32578
|
const offerCode = command === "connect" ? parsed.positionals[1]?.trim() : void 0;
|
|
32319
|
-
const
|
|
32579
|
+
const wantCloud = command === "remote" ? Boolean(parsed.values.cloud || parsed.values.site || !lan) : Boolean(parsed.values.site || parsed.values.cloud);
|
|
32580
|
+
const site = command === "connect" ? offerCode ? { offerCode } : true : wantCloud ? true : void 0;
|
|
32320
32581
|
const surface = command === "web" ? void 0 : command;
|
|
32321
32582
|
return {
|
|
32322
32583
|
command: "web",
|
|
@@ -32484,16 +32745,18 @@ ${helpText}`);
|
|
|
32484
32745
|
`);
|
|
32485
32746
|
return;
|
|
32486
32747
|
}
|
|
32748
|
+
const lan = kind === "remote" && options?.lan === true;
|
|
32487
32749
|
const started = await (io.web ?? startCritiqueCodeWebServer)({
|
|
32488
32750
|
cwd: invocation.cwd ?? io.cwd,
|
|
32489
32751
|
env: io.env ?? process.env,
|
|
32490
32752
|
stdout: io.stdout,
|
|
32491
32753
|
stderr: io.stderr,
|
|
32492
32754
|
open: false,
|
|
32493
|
-
access:
|
|
32755
|
+
access: lan ? "pair" : "loopback",
|
|
32494
32756
|
...options?.anywhere ? { anywhere: true } : {},
|
|
32495
32757
|
...kind === "slack" ? { portals: ["slack"] } : {},
|
|
32496
32758
|
...kind === "telegram" ? { portals: ["telegram"] } : {},
|
|
32759
|
+
...kind === "remote" && !lan ? { site: true } : {},
|
|
32497
32760
|
...kind === "site" ? { site: options?.offerCode ? { offerCode: options.offerCode } : true } : {},
|
|
32498
32761
|
...inject ? { attach: { push: inject } } : {},
|
|
32499
32762
|
...io.driver ? { driver: io.driver } : {},
|
|
@@ -32509,8 +32772,8 @@ ${helpText}`);
|
|
|
32509
32772
|
return;
|
|
32510
32773
|
}
|
|
32511
32774
|
if ("url" in started) {
|
|
32512
|
-
io.stderr.write(kind === "remote" ? `Phone pairing is up. PIN is in the banner above. Kernel stays on this laptop.
|
|
32513
|
-
` : kind === "site" ? `critique.sh/code
|
|
32775
|
+
io.stderr.write(kind === "remote" && lan ? `Phone pairing is up. PIN is in the banner above. Kernel stays on this laptop.
|
|
32776
|
+
` : kind === "remote" || kind === "site" ? `Critique Remote is attached at critique.sh/code. Kernel stays on this laptop.
|
|
32514
32777
|
` : `${kind} is attached. DM the bot. Kernel stays on this laptop.
|
|
32515
32778
|
`);
|
|
32516
32779
|
}
|