@critiquedotsh/harness 0.1.12 → 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 +489 -227
- 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}
|
|
@@ -21384,7 +21526,7 @@ button:focus-visible,input:focus-visible,textarea:focus-visible{outline:2px soli
|
|
|
21384
21526
|
.rail-search{position:relative}
|
|
21385
21527
|
.rail-search svg{position:absolute;left:10px;top:9px;color:var(--faint);pointer-events:none}
|
|
21386
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}
|
|
21387
|
-
.rail .search:focus{border-color:var(--line);background:
|
|
21529
|
+
.rail .search:focus{border-color:var(--line);background:var(--wash)}
|
|
21388
21530
|
#sessions{display:flex;flex-direction:column;gap:2px;min-height:0;overflow:auto;overscroll-behavior:contain;padding-right:1px;flex:1}
|
|
21389
21531
|
.session-row{display:grid;grid-template-columns:minmax(0,1fr) 28px;gap:2px;align-items:center;border-radius:8px}
|
|
21390
21532
|
.session-row:hover,.session-row.on{background:var(--hover)}
|
|
@@ -21400,14 +21542,14 @@ button:focus-visible,input:focus-visible,textarea:focus-visible{outline:2px soli
|
|
|
21400
21542
|
|
|
21401
21543
|
/* main */
|
|
21402
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)}
|
|
21403
|
-
.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}
|
|
21404
21546
|
.topbar-left{display:flex;align-items:center;gap:9px;min-width:0;flex:1}
|
|
21405
21547
|
.session-title{min-width:0;font-size:12.5px;font-weight:600;color:var(--fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
21406
21548
|
.top-actions{display:flex;align-items:center;gap:5px;min-width:0}
|
|
21407
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}
|
|
21408
21550
|
.icon-btn{width:30px;padding:0}
|
|
21409
21551
|
.icon-btn:hover,.toolbar-btn:hover,.icon-btn.on,.toolbar-btn.on{background:var(--hover);color:var(--fg);border-color:var(--line)}
|
|
21410
|
-
.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}
|
|
21411
21553
|
.top-status,.badge{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--faint);font-size:11px}
|
|
21412
21554
|
.badge.err{color:var(--red)}
|
|
21413
21555
|
#stop{color:var(--red);background:rgba(239,119,112,.08)}
|
|
@@ -21422,20 +21564,20 @@ main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:sta
|
|
|
21422
21564
|
#feed.on{display:block}
|
|
21423
21565
|
.turn{margin:0 0 34px;position:relative}
|
|
21424
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}
|
|
21425
|
-
.reply{margin:0;color
|
|
21567
|
+
.reply{margin:0;color:var(--reply);font-size:14px;line-height:1.63;word-break:break-word}
|
|
21426
21568
|
.reply>*:first-child{margin-top:0}.reply>*:last-child{margin-bottom:0}
|
|
21427
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}
|
|
21428
|
-
.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)}
|
|
21429
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)}
|
|
21430
|
-
.reply a{color
|
|
21431
|
-
.reply code{font:12px ui-monospace,Menlo,monospace;background:
|
|
21432
|
-
.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)}
|
|
21433
21575
|
.reply hr{border:0;border-top:1px solid var(--line);margin:16px 0}
|
|
21434
|
-
.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}
|
|
21435
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}
|
|
21436
21578
|
.reply .md-code code{background:none;border:0;padding:0}
|
|
21437
|
-
.md-table{margin:10px 0 14px;overflow:auto;border:1px solid var(--line);border-radius:10px;background
|
|
21438
|
-
.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}
|
|
21439
21581
|
|
|
21440
21582
|
/* activity: each tool is its own row */
|
|
21441
21583
|
.activity{display:grid;gap:5px;margin:9px 0 13px}
|
|
@@ -21447,24 +21589,24 @@ main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:sta
|
|
|
21447
21589
|
.tool-event.running .tool-dot{background:var(--amber);box-shadow:0 0 0 3px rgba(224,170,67,.08)}
|
|
21448
21590
|
.tool-event.done .tool-dot{background:var(--green)}
|
|
21449
21591
|
.tool-event.failed .tool-dot{background:var(--red)}
|
|
21450
|
-
.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}
|
|
21451
21593
|
.tool-phase{color:var(--faint)}
|
|
21452
|
-
.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}
|
|
21453
21595
|
.think{margin:6px 0;color:var(--faint)}
|
|
21454
|
-
.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)}
|
|
21455
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}
|
|
21456
21598
|
.note{padding:5px 2px;background:transparent;border:0;color:var(--faint);font-family:ui-monospace,Menlo,monospace}
|
|
21457
|
-
.alert{background:rgba(239,119,112,.07);border:1px solid rgba(239,119,112,.18);color
|
|
21458
|
-
.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)}
|
|
21459
21601
|
.trust{display:none}
|
|
21460
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}
|
|
21461
21603
|
|
|
21462
21604
|
/* composer */
|
|
21463
|
-
.dock{padding:8px 18px 14px;background:
|
|
21464
|
-
.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)}
|
|
21465
21607
|
.composer-line{display:flex;align-items:flex-end;gap:5px}
|
|
21466
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)}
|
|
21467
|
-
.composer-line textarea::placeholder{color
|
|
21609
|
+
.composer-line textarea::placeholder{color:var(--placeholder)}
|
|
21468
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}
|
|
21469
21611
|
.round-btn:hover,.plus-btn:hover,.mic-btn:hover,.mic-btn.on{background:var(--hover);color:var(--fg)}
|
|
21470
21612
|
.composer-foot{display:flex;align-items:center;gap:6px;padding:3px 3px 1px;min-height:36px}
|
|
@@ -21474,12 +21616,12 @@ main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:sta
|
|
|
21474
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)}
|
|
21475
21617
|
.pick-open .caret,#model-open .caret{opacity:.45;font-size:9px}
|
|
21476
21618
|
.model-ico{width:15px!important;height:15px!important;display:block;flex:0 0 auto;border-radius:4px}
|
|
21477
|
-
.model-fallback{width:15px;height:15px;display:inline-grid;place-items:center;border-radius:4px;background:
|
|
21478
|
-
.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}
|
|
21479
21621
|
.pick-menu.open,#model-menu.open,#mention.open,.cmd-pop.open,.branch-menu.open,.ship-menu.open{display:grid}
|
|
21480
21622
|
.pick-menu{bottom:36px;left:0;min-width:210px;max-height:300px;overflow:auto;overscroll-behavior:contain;padding:5px}
|
|
21481
21623
|
#model-menu{right:0;bottom:36px;width:310px;max-height:360px;grid-template-rows:auto minmax(0,1fr);overscroll-behavior:contain}
|
|
21482
|
-
#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}
|
|
21483
21625
|
#model-list{overflow:auto;overscroll-behavior:contain;max-height:310px;padding:5px}
|
|
21484
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}
|
|
21485
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)}
|
|
@@ -21488,35 +21630,35 @@ main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:sta
|
|
|
21488
21630
|
#send:hover{transform:translateY(-1px);filter:brightness(1.04)}#send.steer{background:#bfe8cf;color:#142219}#send:disabled{opacity:.45;cursor:not-allowed}
|
|
21489
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)}
|
|
21490
21632
|
.autonomy-pill.auto{color:var(--amber);border-color:rgba(224,170,67,.24);background:rgba(224,170,67,.055)}
|
|
21491
|
-
.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:
|
|
21492
|
-
.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)}
|
|
21493
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)}
|
|
21494
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}
|
|
21495
21637
|
|
|
21496
21638
|
/* terminal */
|
|
21497
|
-
.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)}
|
|
21498
21640
|
|
|
21499
21641
|
/* workspace */
|
|
21500
|
-
.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
|
|
21501
|
-
#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}
|
|
21502
21644
|
|
|
21503
21645
|
/* overlays */
|
|
21504
|
-
.sheet{display:none;position:fixed;inset:0;z-index:50;background:
|
|
21505
|
-
#modal{display:none;position:fixed;inset:0;z-index:60;background:
|
|
21506
|
-
.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)}
|
|
21507
21649
|
|
|
21508
21650
|
/* command browser */
|
|
21509
|
-
.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}
|
|
21510
21652
|
|
|
21511
21653
|
/* settings */
|
|
21512
|
-
.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
|
|
21513
|
-
.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:
|
|
21514
|
-
.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}
|
|
21515
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}
|
|
21516
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)}
|
|
21517
21659
|
|
|
21518
21660
|
/* resume picker */
|
|
21519
|
-
.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}
|
|
21520
21662
|
|
|
21521
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)}}
|
|
21522
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}}
|
|
@@ -21624,7 +21766,7 @@ main{min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:sta
|
|
|
21624
21766
|
<button type="button" data-cmd="/login">Login / connect inference</button>
|
|
21625
21767
|
</div>
|
|
21626
21768
|
</div>
|
|
21627
|
-
<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>
|
|
21628
21770
|
<button type="button" class="mic-btn" id="voice" title="Voice input" aria-label="Voice input">
|
|
21629
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>
|
|
21630
21772
|
</button>
|
|
@@ -21797,6 +21939,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
21797
21939
|
var sessionTitleEl = document.getElementById("session-title");
|
|
21798
21940
|
var activeSessionId = null;
|
|
21799
21941
|
var refs = [];
|
|
21942
|
+
var pendingImages = [];
|
|
21800
21943
|
var sessionMentions = [];
|
|
21801
21944
|
var treePaths = [];
|
|
21802
21945
|
var collapsedDirs = {};
|
|
@@ -21897,7 +22040,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
21897
22040
|
|
|
21898
22041
|
function modelIconHtml(option) {
|
|
21899
22042
|
var provider = option && (option.getAttribute("data-provider") || "") || "other";
|
|
21900
|
-
var raw =
|
|
22043
|
+
var raw = iconMap[provider] || iconMap.other || "";
|
|
21901
22044
|
if (raw) return raw;
|
|
21902
22045
|
var label = option && (option.text || option.value) || provider || "model";
|
|
21903
22046
|
var letter = String(label).replace(/^[^a-z0-9]+/i, "").charAt(0).toUpperCase() || "M";
|
|
@@ -22000,7 +22143,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22000
22143
|
btn.type = "button";
|
|
22001
22144
|
btn.className = option.selected ? "on" : "";
|
|
22002
22145
|
btn.textContent = "";
|
|
22003
|
-
var icon = option.getAttribute("data-
|
|
22146
|
+
var icon = option.getAttribute("data-provider") ? modelIconHtml(option) : "";
|
|
22004
22147
|
if (icon) btn.insertAdjacentHTML("beforeend", icon);
|
|
22005
22148
|
var name = document.createElement("span");
|
|
22006
22149
|
name.textContent = option.text || option.value;
|
|
@@ -22287,7 +22430,8 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22287
22430
|
promptQueue.forEach(function (item, index) {
|
|
22288
22431
|
var row = document.createElement("div");
|
|
22289
22432
|
row.className = "queue-item";
|
|
22290
|
-
|
|
22433
|
+
var labelText = typeof item === "string" ? item : (item.text || (item.images && item.images.length ? item.images.length + " image" : ""));
|
|
22434
|
+
row.textContent = labelText;
|
|
22291
22435
|
var rm = document.createElement("button");
|
|
22292
22436
|
rm.type = "button";
|
|
22293
22437
|
rm.textContent = "Remove";
|
|
@@ -22302,12 +22446,13 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22302
22446
|
label.textContent = n ? n + " Queued \u21B5 to Send" : "";
|
|
22303
22447
|
}
|
|
22304
22448
|
|
|
22305
|
-
function enqueuePrompt(text) {
|
|
22306
|
-
promptQueue.push(text);
|
|
22449
|
+
function enqueuePrompt(text, images) {
|
|
22450
|
+
promptQueue.push({ text: text, images: images || [] });
|
|
22307
22451
|
renderQueue();
|
|
22308
22452
|
}
|
|
22309
22453
|
|
|
22310
|
-
function dispatchPrompt(text) {
|
|
22454
|
+
function dispatchPrompt(text, images) {
|
|
22455
|
+
var payloadImages = images || [];
|
|
22311
22456
|
var normalized = text.trim().toLowerCase();
|
|
22312
22457
|
if (normalized === "/resume" || normalized === "resume") {
|
|
22313
22458
|
showResumePicker();
|
|
@@ -22323,7 +22468,8 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22323
22468
|
api("POST", isCmd ? "/api/command" : "/api/prompt", {
|
|
22324
22469
|
text: text,
|
|
22325
22470
|
refs: refs,
|
|
22326
|
-
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 }; })
|
|
22327
22473
|
}).then(function (res) {
|
|
22328
22474
|
if (!res.ok) {
|
|
22329
22475
|
return readError(res, "Request failed").then(function (msg) { addBlock("alert", msg); });
|
|
@@ -22342,7 +22488,10 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22342
22488
|
if (!steerNow && busy) return;
|
|
22343
22489
|
var next = promptQueue.shift();
|
|
22344
22490
|
renderQueue();
|
|
22345
|
-
if (next)
|
|
22491
|
+
if (next) {
|
|
22492
|
+
if (typeof next === "string") dispatchPrompt(next, []);
|
|
22493
|
+
else dispatchPrompt(next.text || "", next.images || []);
|
|
22494
|
+
}
|
|
22346
22495
|
}
|
|
22347
22496
|
|
|
22348
22497
|
function setAlways(on) {
|
|
@@ -22702,8 +22851,8 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
22702
22851
|
var vals = usageHistory.map(function (r) { return r.input + r.output + r.reasoning; });
|
|
22703
22852
|
var max = Math.max.apply(null, vals.concat([1]));
|
|
22704
22853
|
var w = 640, h = 150, gap = 2, bw = Math.max(2, (w - (vals.length - 1) * gap) / vals.length);
|
|
22705
|
-
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=\\"
|
|
22706
|
-
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>";
|
|
22707
22856
|
}
|
|
22708
22857
|
}
|
|
22709
22858
|
var phaseRows = [];
|
|
@@ -23293,16 +23442,18 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23293
23442
|
|
|
23294
23443
|
function submitText(raw, steerNow) {
|
|
23295
23444
|
var text = (raw == null ? inputEl.value : raw).trim();
|
|
23296
|
-
|
|
23297
|
-
if (
|
|
23445
|
+
var images = raw == null ? pendingImages.slice() : [];
|
|
23446
|
+
if (raw == null && (text || images.length)) { inputEl.value = ""; autosizeInput(); }
|
|
23447
|
+
if (!text && !images.length) {
|
|
23298
23448
|
if (steerNow) flushQueue(true);
|
|
23299
23449
|
return;
|
|
23300
23450
|
}
|
|
23451
|
+
if (raw == null) { pendingImages = []; renderChips(); }
|
|
23301
23452
|
if (busy && !steerNow) {
|
|
23302
|
-
enqueuePrompt(text);
|
|
23453
|
+
enqueuePrompt(text, images);
|
|
23303
23454
|
return;
|
|
23304
23455
|
}
|
|
23305
|
-
dispatchPrompt(text);
|
|
23456
|
+
dispatchPrompt(text || "Look at the attached image.", images);
|
|
23306
23457
|
}
|
|
23307
23458
|
|
|
23308
23459
|
function decide(decision) {
|
|
@@ -23421,6 +23572,50 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23421
23572
|
chip.addEventListener("click", function () { sessionMentions.splice(i, 1); renderChips(); });
|
|
23422
23573
|
el.appendChild(chip);
|
|
23423
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;
|
|
23424
23619
|
}
|
|
23425
23620
|
|
|
23426
23621
|
function addRef(path) {
|
|
@@ -23750,6 +23945,7 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23750
23945
|
var files = e.dataTransfer && e.dataTransfer.files;
|
|
23751
23946
|
if (!files) return;
|
|
23752
23947
|
Array.from(files).forEach(function (file) {
|
|
23948
|
+
if (addImageFile(file)) return;
|
|
23753
23949
|
var reader = new FileReader();
|
|
23754
23950
|
reader.onload = function () {
|
|
23755
23951
|
pendingImport = { name: file.name, contents: String(reader.result || "") };
|
|
@@ -23761,6 +23957,26 @@ window.CRITIQUE_CODE_TOKEN = "__CRITIQUE_CODE_TOKEN__";
|
|
|
23761
23957
|
reader.readAsText(file);
|
|
23762
23958
|
});
|
|
23763
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
|
+
});
|
|
23764
23980
|
if (filesBadge) filesBadge.addEventListener("click", function () {
|
|
23765
23981
|
layout.changes = true;
|
|
23766
23982
|
applyLayout();
|
|
@@ -25077,14 +25293,14 @@ async function loadPiTui() {
|
|
|
25077
25293
|
return await import(specifier);
|
|
25078
25294
|
} catch (error) {
|
|
25079
25295
|
const { existsSync: existsSync3 } = await import("node:fs");
|
|
25080
|
-
const { dirname: dirname11, join:
|
|
25296
|
+
const { dirname: dirname11, join: join23 } = await import("node:path");
|
|
25081
25297
|
const { fileURLToPath: fileURLToPath3, pathToFileURL: pathToFileURL3 } = await import("node:url");
|
|
25082
25298
|
const roots = [
|
|
25083
|
-
|
|
25084
|
-
|
|
25299
|
+
join23(dirname11(fileURLToPath3(import.meta.url)), "../../packages/critique-code/.vendor"),
|
|
25300
|
+
join23(dirname11(fileURLToPath3(import.meta.url)), "../../packages/critique-code")
|
|
25085
25301
|
];
|
|
25086
25302
|
for (const root of roots) {
|
|
25087
|
-
const candidate =
|
|
25303
|
+
const candidate = join23(root, "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-tui/dist/index.js");
|
|
25088
25304
|
if (!existsSync3(candidate)) continue;
|
|
25089
25305
|
return await import(pathToFileURL3(candidate).href);
|
|
25090
25306
|
}
|
|
@@ -25236,7 +25452,7 @@ async function createInteractiveSettingsUi(input) {
|
|
|
25236
25452
|
init_zod();
|
|
25237
25453
|
import { spawn as spawn3 } from "node:child_process";
|
|
25238
25454
|
import { accessSync, constants } from "node:fs";
|
|
25239
|
-
import { delimiter as delimiter2, join as
|
|
25455
|
+
import { delimiter as delimiter2, join as join16 } from "node:path";
|
|
25240
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`.";
|
|
25241
25457
|
var TOOL_COMMANDS = [
|
|
25242
25458
|
"review",
|
|
@@ -25500,7 +25716,7 @@ function resolveCritiqueCliBinary(env = process.env) {
|
|
|
25500
25716
|
for (const directory of pathEnv.split(delimiter2)) {
|
|
25501
25717
|
if (!directory) continue;
|
|
25502
25718
|
for (const name of names) {
|
|
25503
|
-
const candidate =
|
|
25719
|
+
const candidate = join16(directory, name);
|
|
25504
25720
|
try {
|
|
25505
25721
|
accessSync(candidate, mode);
|
|
25506
25722
|
return candidate;
|
|
@@ -25736,7 +25952,7 @@ var AUTHOR_PALETTE_ITEMS = [
|
|
|
25736
25952
|
{ value: "/repeat", label: "Repeat", description: "Re-run the last command" },
|
|
25737
25953
|
{ value: "/theme", label: "Theme", description: "Color and compact layout for this TUI" },
|
|
25738
25954
|
{ value: "/alias", label: "Aliases", description: "Bind shortcuts to command chains" },
|
|
25739
|
-
{ value: "/remote", label: "Remote", description: "
|
|
25955
|
+
{ value: "/remote", label: "Remote", description: "Attach critique.sh/code via Critique Remote" },
|
|
25740
25956
|
{ value: "/connect", label: "Connect website", description: "Attach critique.sh/code to this laptop" },
|
|
25741
25957
|
{ value: "/slack", label: "Slack", description: "Attach Slack Socket Mode to this laptop session" },
|
|
25742
25958
|
{ value: "/telegram", label: "Telegram", description: "Attach a Telegram bot to this laptop session" },
|
|
@@ -25787,7 +26003,7 @@ function formatAuthorHelp() {
|
|
|
25787
26003
|
" /context tokens and loaded files",
|
|
25788
26004
|
" /status /logs /cost /doctor",
|
|
25789
26005
|
" /undo /repeat /theme /alias",
|
|
25790
|
-
" /remote
|
|
26006
|
+
" /remote attach critique.sh/code (Critique Remote). /remote lan for Wi-Fi PIN",
|
|
25791
26007
|
" /connect attach critique.sh/code to this laptop (paste the website code)",
|
|
25792
26008
|
" /slack attach Slack Socket Mode; DMs run on this laptop",
|
|
25793
26009
|
" /telegram attach a Telegram bot; chats run on this laptop",
|
|
@@ -25976,6 +26192,7 @@ function parseAuthorCommand(line, aliases = {}) {
|
|
|
25976
26192
|
if (lower.startsWith("/alias ")) return parseAlias(expanded);
|
|
25977
26193
|
if (lower === "/remote" || lower === "remote") return { kind: "remote" };
|
|
25978
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 };
|
|
25979
26196
|
if (lower === "/connect" || lower === "connect" || lower === "/site" || lower === "site") return { kind: "site" };
|
|
25980
26197
|
if (lower.startsWith("/connect ")) return { kind: "site", offerCode: expanded.slice(9).trim() };
|
|
25981
26198
|
if (lower === "/slack" || lower === "slack") return { kind: "slack" };
|
|
@@ -25992,7 +26209,7 @@ function parseAuthorCommand(line, aliases = {}) {
|
|
|
25992
26209
|
// lib/finish/critique-code-web-changes.ts
|
|
25993
26210
|
import { execFileSync } from "node:child_process";
|
|
25994
26211
|
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
25995
|
-
import { readFile as
|
|
26212
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
25996
26213
|
import { dirname as dirname8, isAbsolute as isAbsolute16, relative as relative9, resolve as resolve11 } from "node:path";
|
|
25997
26214
|
var SKIP_TREE_SEGMENTS = /* @__PURE__ */ new Set([".git", "node_modules", ".critique"]);
|
|
25998
26215
|
function git3(root, args) {
|
|
@@ -26155,7 +26372,7 @@ async function workingTreeFilePatch(root, path2) {
|
|
|
26155
26372
|
} catch {
|
|
26156
26373
|
}
|
|
26157
26374
|
try {
|
|
26158
|
-
const contents = await
|
|
26375
|
+
const contents = await readFile18(`${root}/${path2}`, "utf8");
|
|
26159
26376
|
const lines = contents.split("\n");
|
|
26160
26377
|
const body = lines.map((line) => `+${line}`).join("\n");
|
|
26161
26378
|
return {
|
|
@@ -26377,9 +26594,9 @@ function commitMessageFromReview(input) {
|
|
|
26377
26594
|
|
|
26378
26595
|
// lib/finish/critique-code-skills.ts
|
|
26379
26596
|
init_critique_code_runtime_config();
|
|
26380
|
-
import { cp, mkdir as
|
|
26597
|
+
import { cp, mkdir as mkdir13, readdir as readdir2, readFile as readFile19, writeFile as writeFile12 } from "node:fs/promises";
|
|
26381
26598
|
import { homedir as homedir2 } from "node:os";
|
|
26382
|
-
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";
|
|
26383
26600
|
var CRITIQUE_CODE_SKILL_SCHEMA = "critique.code-skill.v1";
|
|
26384
26601
|
var MAX_SKILL_BYTES = 64 * 1024;
|
|
26385
26602
|
var MAX_IMPORTED_SKILLS = 80;
|
|
@@ -26601,16 +26818,16 @@ var PROJECT_SKILL_DIRS = [
|
|
|
26601
26818
|
];
|
|
26602
26819
|
function userSkillDirs(home, userHome) {
|
|
26603
26820
|
return [
|
|
26604
|
-
{ root:
|
|
26605
|
-
{ root:
|
|
26606
|
-
{ root:
|
|
26607
|
-
{ root:
|
|
26608
|
-
{ root:
|
|
26609
|
-
{ 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" }
|
|
26610
26827
|
];
|
|
26611
26828
|
}
|
|
26612
26829
|
function critiqueCodeImportedSkillsPath(home) {
|
|
26613
|
-
return
|
|
26830
|
+
return join17(home, "skills");
|
|
26614
26831
|
}
|
|
26615
26832
|
function skillId(value) {
|
|
26616
26833
|
const id4 = value.trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -26637,7 +26854,7 @@ function parseFrontmatter(markdown) {
|
|
|
26637
26854
|
async function readSkillFile(file, source, origin, fallbackId) {
|
|
26638
26855
|
let markdown;
|
|
26639
26856
|
try {
|
|
26640
|
-
markdown = await
|
|
26857
|
+
markdown = await readFile19(file, "utf8");
|
|
26641
26858
|
} catch {
|
|
26642
26859
|
return void 0;
|
|
26643
26860
|
}
|
|
@@ -26665,7 +26882,7 @@ async function loadSkillsFromRoot(root, source) {
|
|
|
26665
26882
|
}
|
|
26666
26883
|
const skills = [];
|
|
26667
26884
|
for (const entry of entries) {
|
|
26668
|
-
const nested4 =
|
|
26885
|
+
const nested4 = join17(root, entry, "SKILL.md");
|
|
26669
26886
|
const skill = await readSkillFile(nested4, source, nested4, entry);
|
|
26670
26887
|
if (skill) skills.push(skill);
|
|
26671
26888
|
}
|
|
@@ -26715,7 +26932,7 @@ async function discoverCritiqueCodeSkills(input) {
|
|
|
26715
26932
|
}
|
|
26716
26933
|
let imported = 0;
|
|
26717
26934
|
for (const dir of PROJECT_SKILL_DIRS) {
|
|
26718
|
-
const root =
|
|
26935
|
+
const root = join17(cwd, dir.relative);
|
|
26719
26936
|
if (!contained(cwd, root)) continue;
|
|
26720
26937
|
for (const skill of await loadSkillsFromRoot(root, dir.source)) {
|
|
26721
26938
|
if (skill.source !== "builtin" && skill.source !== "imported") {
|
|
@@ -26747,20 +26964,20 @@ function formatCritiqueCodeSkillsList(skills) {
|
|
|
26747
26964
|
`;
|
|
26748
26965
|
}
|
|
26749
26966
|
async function stageCritiqueCodeSkills(input) {
|
|
26750
|
-
const dest =
|
|
26751
|
-
await
|
|
26967
|
+
const dest = join17(input.agent_root, "skills");
|
|
26968
|
+
await mkdir13(dest, { recursive: true });
|
|
26752
26969
|
for (const skill of input.skills) {
|
|
26753
26970
|
const id4 = skillId(skill.id);
|
|
26754
26971
|
if (!id4) continue;
|
|
26755
|
-
const folder =
|
|
26756
|
-
await
|
|
26972
|
+
const folder = join17(dest, id4);
|
|
26973
|
+
await mkdir13(folder, { recursive: true });
|
|
26757
26974
|
const header = `---
|
|
26758
26975
|
name: ${skill.id}
|
|
26759
26976
|
description: ${skill.description.replace(/\n/g, " ").slice(0, 1024)}
|
|
26760
26977
|
---
|
|
26761
26978
|
|
|
26762
26979
|
`;
|
|
26763
|
-
await
|
|
26980
|
+
await writeFile12(join17(folder, "SKILL.md"), `${header}${skill.body.trim()}
|
|
26764
26981
|
`, "utf8");
|
|
26765
26982
|
}
|
|
26766
26983
|
return dest;
|
|
@@ -26769,7 +26986,7 @@ async function importCritiqueCodeSkills(input) {
|
|
|
26769
26986
|
const env = input.env ?? process.env;
|
|
26770
26987
|
const home = critiqueCodeHome(env);
|
|
26771
26988
|
const destRoot = critiqueCodeImportedSkillsPath(home);
|
|
26772
|
-
await
|
|
26989
|
+
await mkdir13(destRoot, { recursive: true });
|
|
26773
26990
|
const discovered = await discoverCritiqueCodeSkills({
|
|
26774
26991
|
cwd: input.cwd,
|
|
26775
26992
|
env,
|
|
@@ -26782,18 +26999,18 @@ async function importCritiqueCodeSkills(input) {
|
|
|
26782
26999
|
skipped.push(skill.id);
|
|
26783
27000
|
continue;
|
|
26784
27001
|
}
|
|
26785
|
-
const folder =
|
|
26786
|
-
await
|
|
27002
|
+
const folder = join17(destRoot, skill.id);
|
|
27003
|
+
await mkdir13(folder, { recursive: true });
|
|
26787
27004
|
if (skill.origin.endsWith(`${sep10}SKILL.md`)) {
|
|
26788
27005
|
try {
|
|
26789
|
-
await cp(skill.origin,
|
|
26790
|
-
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") });
|
|
26791
27008
|
continue;
|
|
26792
27009
|
} catch {
|
|
26793
27010
|
}
|
|
26794
27011
|
}
|
|
26795
|
-
await
|
|
26796
|
-
|
|
27012
|
+
await writeFile12(
|
|
27013
|
+
join17(folder, "SKILL.md"),
|
|
26797
27014
|
`---
|
|
26798
27015
|
name: ${skill.id}
|
|
26799
27016
|
description: ${skill.description.replace(/\n/g, " ")}
|
|
@@ -26803,7 +27020,7 @@ ${skill.body.trim()}
|
|
|
26803
27020
|
`,
|
|
26804
27021
|
"utf8"
|
|
26805
27022
|
);
|
|
26806
|
-
imported.push({ ...skill, source: "imported", origin:
|
|
27023
|
+
imported.push({ ...skill, source: "imported", origin: join17(folder, "SKILL.md") });
|
|
26807
27024
|
}
|
|
26808
27025
|
return { home, imported, skipped };
|
|
26809
27026
|
}
|
|
@@ -26812,9 +27029,9 @@ ${skill.body.trim()}
|
|
|
26812
27029
|
import { spawn as spawn4 } from "node:child_process";
|
|
26813
27030
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
26814
27031
|
import { createRequire } from "node:module";
|
|
26815
|
-
import { mkdtemp as mkdtemp3, readFile as
|
|
27032
|
+
import { mkdtemp as mkdtemp3, readFile as readFile20, rm as rm3 } from "node:fs/promises";
|
|
26816
27033
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
26817
|
-
import { dirname as dirname9, join as
|
|
27034
|
+
import { dirname as dirname9, join as join18 } from "node:path";
|
|
26818
27035
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
26819
27036
|
|
|
26820
27037
|
// lib/inference/qwen3-asr.ts
|
|
@@ -26908,8 +27125,8 @@ function resolveBundledFfmpegPath(from = import.meta.url) {
|
|
|
26908
27125
|
try {
|
|
26909
27126
|
let dir = dirname9(fileURLToPath2(from));
|
|
26910
27127
|
for (let i = 0; i < 10; i++) {
|
|
26911
|
-
const harnessPkg =
|
|
26912
|
-
const pkg =
|
|
27128
|
+
const harnessPkg = join18(dir, "packages/critique-code/package.json");
|
|
27129
|
+
const pkg = join18(dir, "package.json");
|
|
26913
27130
|
if (existsSync2(harnessPkg)) bases.push(pathToFileURL2(harnessPkg).href);
|
|
26914
27131
|
if (existsSync2(pkg)) {
|
|
26915
27132
|
try {
|
|
@@ -26946,8 +27163,8 @@ function listVoiceRecorderCandidates(input) {
|
|
|
26946
27163
|
}
|
|
26947
27164
|
async function recordMicrophoneWav(input) {
|
|
26948
27165
|
const run = input.spawn ?? spawn4;
|
|
26949
|
-
const dir = await mkdtemp3(
|
|
26950
|
-
const file =
|
|
27166
|
+
const dir = await mkdtemp3(join18(tmpdir5(), "critique-code-voice-"));
|
|
27167
|
+
const file = join18(dir, "clip.wav");
|
|
26951
27168
|
const stop = input.waitForStop ?? (input.stdin ? () => waitForEnter(input.stdin) : void 0);
|
|
26952
27169
|
if (!stop) {
|
|
26953
27170
|
await rm3(dir, { recursive: true, force: true });
|
|
@@ -26966,7 +27183,7 @@ async function recordMicrophoneWav(input) {
|
|
|
26966
27183
|
settled = true;
|
|
26967
27184
|
clearTimeout(timeout);
|
|
26968
27185
|
try {
|
|
26969
|
-
const wav = await
|
|
27186
|
+
const wav = await readFile20(file);
|
|
26970
27187
|
if (wav.length >= 44) {
|
|
26971
27188
|
resolve14({ wav });
|
|
26972
27189
|
return;
|
|
@@ -27283,7 +27500,7 @@ function createPiAuthorTaskProjectedTool(projection) {
|
|
|
27283
27500
|
init_pi_source_tool();
|
|
27284
27501
|
|
|
27285
27502
|
// lib/finish/critique-code-workspace-memory.ts
|
|
27286
|
-
import { chmod as chmod3, mkdir as
|
|
27503
|
+
import { chmod as chmod3, mkdir as mkdir14, readFile as readFile21, writeFile as writeFile13 } from "node:fs/promises";
|
|
27287
27504
|
import { dirname as dirname10 } from "node:path";
|
|
27288
27505
|
var MAX_MEMORY_RECORDS = 200;
|
|
27289
27506
|
var MAX_MEMORY_VALUE_CHARS = 8192;
|
|
@@ -27347,7 +27564,7 @@ var CritiqueCodeWorkspaceMemory = class {
|
|
|
27347
27564
|
}
|
|
27348
27565
|
async load() {
|
|
27349
27566
|
try {
|
|
27350
|
-
const raw = await
|
|
27567
|
+
const raw = await readFile21(this.#filePath, "utf8");
|
|
27351
27568
|
const parsed = JSON.parse(raw);
|
|
27352
27569
|
this.#records = Array.isArray(parsed.records) ? parsed.records.filter(isMemoryRecord).slice(-MAX_MEMORY_RECORDS) : [];
|
|
27353
27570
|
} catch (error) {
|
|
@@ -27375,8 +27592,8 @@ var CritiqueCodeWorkspaceMemory = class {
|
|
|
27375
27592
|
if (this.#records.length > MAX_MEMORY_RECORDS) {
|
|
27376
27593
|
this.#records = this.#records.slice(-MAX_MEMORY_RECORDS);
|
|
27377
27594
|
}
|
|
27378
|
-
await
|
|
27379
|
-
await
|
|
27595
|
+
await mkdir14(dirname10(this.#filePath), { recursive: true });
|
|
27596
|
+
await writeFile13(this.#filePath, `${JSON.stringify({ records: this.#records })}
|
|
27380
27597
|
`, { mode: 384 });
|
|
27381
27598
|
await chmod3(this.#filePath, 384);
|
|
27382
27599
|
}
|
|
@@ -27398,7 +27615,7 @@ var CritiqueCodeWorkspaceMemory = class {
|
|
|
27398
27615
|
|
|
27399
27616
|
// lib/finish/critique-code-workspace-tool.ts
|
|
27400
27617
|
init_zod();
|
|
27401
|
-
import { readFile as
|
|
27618
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
27402
27619
|
|
|
27403
27620
|
// lib/finish/critique-code-ts-edit.ts
|
|
27404
27621
|
import ts2 from "typescript";
|
|
@@ -27442,7 +27659,7 @@ function renameTsIdentifier(input) {
|
|
|
27442
27659
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
27443
27660
|
import { readFileSync as readFileSync3, readdirSync } from "node:fs";
|
|
27444
27661
|
import { createServer } from "node:net";
|
|
27445
|
-
import { join as
|
|
27662
|
+
import { join as join19 } from "node:path";
|
|
27446
27663
|
var SKIP_DIR_NAMES = /* @__PURE__ */ new Set([".git", "node_modules", ".critique", "dist"]);
|
|
27447
27664
|
var SUBPROCESS_TIMEOUT_MS = 4e3;
|
|
27448
27665
|
var FETCH_TIMEOUT_MS = 8e3;
|
|
@@ -27531,7 +27748,7 @@ function walkWorkspaceFiles(root, pattern, maxHits) {
|
|
|
27531
27748
|
if (hits.length >= maxHits) return;
|
|
27532
27749
|
if (SKIP_DIR_NAMES.has(entry.name)) continue;
|
|
27533
27750
|
const rel = relDir ? `${relDir}/${entry.name}` : entry.name;
|
|
27534
|
-
const abs =
|
|
27751
|
+
const abs = join19(absDir, entry.name);
|
|
27535
27752
|
if (entry.isDirectory()) {
|
|
27536
27753
|
visit(abs, rel);
|
|
27537
27754
|
continue;
|
|
@@ -27582,7 +27799,7 @@ function grepWorkspaceJs(root, query, maxHits) {
|
|
|
27582
27799
|
if (hits.length >= maxHits) break;
|
|
27583
27800
|
let bytes;
|
|
27584
27801
|
try {
|
|
27585
|
-
bytes = readFileSync3(
|
|
27802
|
+
bytes = readFileSync3(join19(root, rel));
|
|
27586
27803
|
} catch {
|
|
27587
27804
|
continue;
|
|
27588
27805
|
}
|
|
@@ -27894,19 +28111,19 @@ var PiWorkspaceToolProjection = class {
|
|
|
27894
28111
|
return { hits: grepWorkspaceIntel(this.#root, input.query) };
|
|
27895
28112
|
case "diff": {
|
|
27896
28113
|
if (!input.path) throw new Error("diff requires path.");
|
|
27897
|
-
const current = await
|
|
28114
|
+
const current = await readFile22(safeRepoPath(this.#root, input.path), "utf8");
|
|
27898
28115
|
const previous = input.before ?? "";
|
|
27899
28116
|
return { path: input.path, patch: unifiedDiff(previous, input.after ?? current, input.path) };
|
|
27900
28117
|
}
|
|
27901
28118
|
case "parse_config": {
|
|
27902
28119
|
if (!input.path) throw new Error("parse_config requires path.");
|
|
27903
|
-
const text = await
|
|
28120
|
+
const text = await readFile22(safeRepoPath(this.#root, input.path), "utf8");
|
|
27904
28121
|
return parseStructuredConfig(text, input.kind ?? "auto");
|
|
27905
28122
|
}
|
|
27906
28123
|
case "env_keys": {
|
|
27907
28124
|
const rel = input.path ?? ".env";
|
|
27908
28125
|
try {
|
|
27909
|
-
const text = await
|
|
28126
|
+
const text = await readFile22(safeRepoPath(this.#root, rel), "utf8");
|
|
27910
28127
|
return { path: rel, keys: parseDotenvKeys(text), limitation: "Values are never returned." };
|
|
27911
28128
|
} catch {
|
|
27912
28129
|
return { path: rel, keys: [], limitation: "File missing. Values are never returned." };
|
|
@@ -27925,7 +28142,7 @@ var PiWorkspaceToolProjection = class {
|
|
|
27925
28142
|
return { records: this.#memory.recall(input.query ?? input.key ?? "") };
|
|
27926
28143
|
case "rename_ts": {
|
|
27927
28144
|
if (!input.path || !input.from || !input.to) throw new Error("rename_ts requires path, from, and to.");
|
|
27928
|
-
const source = await
|
|
28145
|
+
const source = await readFile22(safeRepoPath(this.#root, input.path), "utf8");
|
|
27929
28146
|
const renamed = renameTsIdentifier({ source, fileName: input.path, from: input.from, to: input.to });
|
|
27930
28147
|
return {
|
|
27931
28148
|
...renamed,
|
|
@@ -28140,7 +28357,7 @@ function wrapAuthorWrite(inner, onWrite, workspaceRoot) {
|
|
|
28140
28357
|
let previous = null;
|
|
28141
28358
|
if (path2) {
|
|
28142
28359
|
try {
|
|
28143
|
-
previous = await
|
|
28360
|
+
previous = await readFile23(join20(workspaceRoot, path2), "utf8");
|
|
28144
28361
|
} catch {
|
|
28145
28362
|
previous = null;
|
|
28146
28363
|
}
|
|
@@ -28159,7 +28376,7 @@ function liveSourceState(state) {
|
|
|
28159
28376
|
}
|
|
28160
28377
|
async function loadReleasedFile(repositoryRoot, name, maxChars) {
|
|
28161
28378
|
try {
|
|
28162
|
-
const text = (await
|
|
28379
|
+
const text = (await readFile23(join20(repositoryRoot, name), "utf8")).trim();
|
|
28163
28380
|
if (!text) return void 0;
|
|
28164
28381
|
const release = await patternSecretEgress().release({ kind: "model_prompt", content: text.slice(0, maxChars) });
|
|
28165
28382
|
return release.content;
|
|
@@ -28241,14 +28458,14 @@ async function runLocalCritiqueCodeAuthor(input) {
|
|
|
28241
28458
|
const storeRoot = input.store_root ?? defaultCritiqueCodeStoreRoot(repositoryRoot);
|
|
28242
28459
|
const sessionOps = new FileSessionOpsStore(storeRoot);
|
|
28243
28460
|
await sessionOps.load();
|
|
28244
|
-
const workspaceMemory = new CritiqueCodeWorkspaceMemory(
|
|
28461
|
+
const workspaceMemory = new CritiqueCodeWorkspaceMemory(join20(storeRoot, "workspace-memory.json"));
|
|
28245
28462
|
await workspaceMemory.load();
|
|
28246
|
-
const agentRoot = input.agent_root ??
|
|
28463
|
+
const agentRoot = input.agent_root ?? join20(tmpdir6(), "critique-code-pi-agent");
|
|
28247
28464
|
if (!isAbsolute19(agentRoot)) {
|
|
28248
28465
|
reader.close();
|
|
28249
28466
|
return { kind: "kernel_required", limitation: "Pi agent root must be an absolute controller-owned directory." };
|
|
28250
28467
|
}
|
|
28251
|
-
if (!input.agent_root) await
|
|
28468
|
+
if (!input.agent_root) await mkdir15(agentRoot, { recursive: true });
|
|
28252
28469
|
const conversationIdSeed = `pi_${createHash38("sha256").update(repositoryRoot).digest("hex").slice(0, 24)}`;
|
|
28253
28470
|
const review = input.review ?? runLocalCritiqueCodeReview;
|
|
28254
28471
|
const checkpoints = new FileReviewCheckpointStore(storeRoot);
|
|
@@ -28690,7 +28907,7 @@ ${prior}`.trim();
|
|
|
28690
28907
|
emitReviewController({ reviewing: false });
|
|
28691
28908
|
}
|
|
28692
28909
|
};
|
|
28693
|
-
const promptAuthor = async (prompt) => {
|
|
28910
|
+
const promptAuthor = async (prompt, images) => {
|
|
28694
28911
|
await ensureSession();
|
|
28695
28912
|
noteWithheld(prompt);
|
|
28696
28913
|
reader.pause();
|
|
@@ -28708,7 +28925,8 @@ ${prior}`.trim();
|
|
|
28708
28925
|
const turn = await authors.prompt({
|
|
28709
28926
|
conversation_id: conversationId2,
|
|
28710
28927
|
prompt: outbound,
|
|
28711
|
-
timeout_ms: timeoutMs
|
|
28928
|
+
timeout_ms: timeoutMs,
|
|
28929
|
+
...images && images.length > 0 ? { images } : {}
|
|
28712
28930
|
});
|
|
28713
28931
|
await sessionOps.recordCost({
|
|
28714
28932
|
at: now().toISOString(),
|
|
@@ -28761,10 +28979,17 @@ ${prior}`.trim();
|
|
|
28761
28979
|
ensureStarted(input.intent.trim());
|
|
28762
28980
|
}
|
|
28763
28981
|
for (; ; ) {
|
|
28764
|
-
const
|
|
28765
|
-
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
|
+
})) : [];
|
|
28766
28991
|
let command = authorCommand(line, sessionOps.state().aliases, skills);
|
|
28767
|
-
if (!command && !line.trim()) continue;
|
|
28992
|
+
if (!command && !line.trim() && packedImages.length === 0) continue;
|
|
28768
28993
|
if (command && command.kind !== "repeat" && command.kind !== "palette" && command.kind !== "help") {
|
|
28769
28994
|
await sessionOps.setLastCommand(line.trim());
|
|
28770
28995
|
}
|
|
@@ -28813,14 +29038,14 @@ ${prior}`.trim();
|
|
|
28813
29038
|
}
|
|
28814
29039
|
if (command?.kind === "remote" || command?.kind === "slack" || command?.kind === "telegram" || command?.kind === "site") {
|
|
28815
29040
|
if (!input.on_surface) {
|
|
28816
|
-
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.
|
|
28817
29042
|
`);
|
|
28818
29043
|
continue;
|
|
28819
29044
|
}
|
|
28820
29045
|
try {
|
|
28821
29046
|
await input.on_surface(
|
|
28822
29047
|
command.kind,
|
|
28823
|
-
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 } : {}
|
|
28824
29049
|
);
|
|
28825
29050
|
} catch (error) {
|
|
28826
29051
|
say(`${error instanceof Error ? error.message : String(error)}
|
|
@@ -28871,7 +29096,7 @@ ${prior}`.trim();
|
|
|
28871
29096
|
}
|
|
28872
29097
|
}
|
|
28873
29098
|
if (thread.action === "fork") {
|
|
28874
|
-
const id5 =
|
|
29099
|
+
const id5 = randomBytes2(6).toString("hex");
|
|
28875
29100
|
const briefing = withheld.trim();
|
|
28876
29101
|
const from = activeThread;
|
|
28877
29102
|
switchThread(id5, true);
|
|
@@ -28891,7 +29116,7 @@ ${briefing}
|
|
|
28891
29116
|
`);
|
|
28892
29117
|
continue;
|
|
28893
29118
|
}
|
|
28894
|
-
const id4 = thread.id?.trim() ||
|
|
29119
|
+
const id4 = thread.id?.trim() || randomBytes2(6).toString("hex");
|
|
28895
29120
|
switchThread(id4, thread.action === "new");
|
|
28896
29121
|
await sessionOps.touchSession({
|
|
28897
29122
|
id: id4,
|
|
@@ -28985,7 +29210,7 @@ ${briefing}
|
|
|
28985
29210
|
`);
|
|
28986
29211
|
continue;
|
|
28987
29212
|
}
|
|
28988
|
-
const id4 =
|
|
29213
|
+
const id4 = randomBytes2(4).toString("hex");
|
|
28989
29214
|
await sessionOps.addSnapshot({
|
|
28990
29215
|
id: id4,
|
|
28991
29216
|
label: command.label?.trim() || `checkpoint ${id4}`,
|
|
@@ -29051,10 +29276,10 @@ ${briefing}
|
|
|
29051
29276
|
const html = command.format === "html" ? `<pre>${markdown.replaceAll("&", "&").replaceAll("<", "<")}</pre>
|
|
29052
29277
|
` : markdown;
|
|
29053
29278
|
const name = `session-${activeThread}.${command.format === "html" ? "html" : "md"}`;
|
|
29054
|
-
const directory =
|
|
29055
|
-
await
|
|
29056
|
-
const target =
|
|
29057
|
-
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 });
|
|
29058
29283
|
say(`Exported ${target}
|
|
29059
29284
|
`);
|
|
29060
29285
|
continue;
|
|
@@ -29406,9 +29631,9 @@ ${current.map((path3) => `- ${path3}`).join("\n")}
|
|
|
29406
29631
|
say("Nothing to undo. /rollback restores a full checkpoint.\n");
|
|
29407
29632
|
continue;
|
|
29408
29633
|
}
|
|
29409
|
-
const target =
|
|
29634
|
+
const target = join20(repositoryRoot, entry.path);
|
|
29410
29635
|
if (entry.previous === null) await unlink4(target).catch(() => void 0);
|
|
29411
|
-
else await
|
|
29636
|
+
else await writeFile14(target, entry.previous);
|
|
29412
29637
|
say(`Undid ${entry.path}.
|
|
29413
29638
|
`);
|
|
29414
29639
|
continue;
|
|
@@ -29544,8 +29769,8 @@ ${current.map((path3) => `- ${path3}`).join("\n")}
|
|
|
29544
29769
|
if (voiceMode) listenNow = true;
|
|
29545
29770
|
continue;
|
|
29546
29771
|
}
|
|
29547
|
-
ensureStarted(line.trim());
|
|
29548
|
-
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);
|
|
29549
29774
|
if (voiceMode) listenNow = true;
|
|
29550
29775
|
}
|
|
29551
29776
|
} finally {
|
|
@@ -29571,10 +29796,10 @@ ${current.map((path3) => `- ${path3}`).join("\n")}
|
|
|
29571
29796
|
|
|
29572
29797
|
// lib/finish/critique-code-web-server.ts
|
|
29573
29798
|
init_change_capsule();
|
|
29574
|
-
import { randomBytes as
|
|
29799
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
29575
29800
|
import { createServer as createServer2 } from "node:http";
|
|
29576
|
-
import { mkdir as
|
|
29577
|
-
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";
|
|
29578
29803
|
import { execFileSync as execFileSync3, spawn as spawn7 } from "node:child_process";
|
|
29579
29804
|
|
|
29580
29805
|
// lib/finish/critique-code-line-hub.ts
|
|
@@ -29788,23 +30013,39 @@ function originAllowed(input) {
|
|
|
29788
30013
|
return parsed.host.toLowerCase() === host;
|
|
29789
30014
|
}
|
|
29790
30015
|
function formatRemoteBanner(input) {
|
|
29791
|
-
const
|
|
29792
|
-
|
|
29793
|
-
|
|
29794
|
-
|
|
29795
|
-
|
|
29796
|
-
|
|
29797
|
-
|
|
29798
|
-
|
|
29799
|
-
|
|
29800
|
-
|
|
29801
|
-
|
|
29802
|
-
|
|
29803
|
-
|
|
29804
|
-
|
|
29805
|
-
|
|
29806
|
-
|
|
29807
|
-
|
|
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");
|
|
29808
30049
|
}
|
|
29809
30050
|
function withToken(url, token) {
|
|
29810
30051
|
const parsed = new URL(url);
|
|
@@ -29886,8 +30127,8 @@ function spawnTunnel(command, args) {
|
|
|
29886
30127
|
|
|
29887
30128
|
// lib/finish/critique-code-portals.ts
|
|
29888
30129
|
init_critique_code_runtime_config();
|
|
29889
|
-
import { mkdir as
|
|
29890
|
-
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";
|
|
29891
30132
|
var CRITIQUE_CODE_PORTALS_SCHEMA = "critique.code-portals.v1";
|
|
29892
30133
|
function isRecord2(value) {
|
|
29893
30134
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -29952,7 +30193,7 @@ async function loadCritiqueCodePortals(env = process.env) {
|
|
|
29952
30193
|
const fromEnv = portalsFromEnv(env);
|
|
29953
30194
|
const home = critiqueCodeHome(env);
|
|
29954
30195
|
try {
|
|
29955
|
-
const raw = JSON.parse(await
|
|
30196
|
+
const raw = JSON.parse(await readFile24(join21(home, "portals.json"), "utf8"));
|
|
29956
30197
|
const stored = parseStoredPortals(raw);
|
|
29957
30198
|
return {
|
|
29958
30199
|
schema_version: CRITIQUE_CODE_PORTALS_SCHEMA,
|
|
@@ -30289,27 +30530,31 @@ async function startCritiqueCodeSiteRelay(input) {
|
|
|
30289
30530
|
repository: input.repository?.trim() || basename3(input.cwd),
|
|
30290
30531
|
cwd: input.cwd
|
|
30291
30532
|
};
|
|
30292
|
-
const claimed =
|
|
30293
|
-
|
|
30294
|
-
...
|
|
30295
|
-
})
|
|
30533
|
+
const claimed = await postJson(fetchImpl, `${origin}/api/new/v1/code/relay/sessions`, headers, {
|
|
30534
|
+
...machine,
|
|
30535
|
+
...input.offerCode ? { code: input.offerCode } : {}
|
|
30536
|
+
});
|
|
30296
30537
|
if (!claimed.ok) {
|
|
30297
30538
|
return { limitation: claimed.error || "critique.sh did not accept this PC." };
|
|
30298
30539
|
}
|
|
30299
|
-
const agentId = String(claimed.body.agentId ?? "");
|
|
30540
|
+
const agentId = String(claimed.body.id ?? claimed.body.agentId ?? "");
|
|
30300
30541
|
const agentToken = String(claimed.body.agentToken ?? "");
|
|
30542
|
+
const browserUrl = String(claimed.body.browser_url ?? `${origin}/code`);
|
|
30301
30543
|
if (!agentId || !agentToken) {
|
|
30302
30544
|
return { limitation: "critique.sh did not return a machine token." };
|
|
30303
30545
|
}
|
|
30304
|
-
input.note?.(`
|
|
30546
|
+
input.note?.(`Connected to Critique Remote. Open ${browserUrl} \xB7 ${machine.hostname} \xB7 ${machine.repository}. Kernel stays on this laptop.`);
|
|
30305
30547
|
const abort = new AbortController();
|
|
30548
|
+
const baseInterval = input.intervalMs ?? 800;
|
|
30549
|
+
const maxInterval = input.maxIntervalMs ?? 3e4;
|
|
30306
30550
|
const loop = (async () => {
|
|
30307
30551
|
const sleep = input.sleep ?? defaultSleep2;
|
|
30552
|
+
let delay = baseInterval;
|
|
30308
30553
|
while (!abort.signal.aborted) {
|
|
30309
30554
|
const events = input.takeEvents().map((event) => ({ ...event }));
|
|
30310
30555
|
const synced = await postJson(
|
|
30311
30556
|
fetchImpl,
|
|
30312
|
-
`${origin}/api/new/v1/code/
|
|
30557
|
+
`${origin}/api/new/v1/code/relay/agent/${agentId}`,
|
|
30313
30558
|
{
|
|
30314
30559
|
authorization: `Bearer ${agentToken}`,
|
|
30315
30560
|
"content-type": "application/json"
|
|
@@ -30320,17 +30565,21 @@ async function startCritiqueCodeSiteRelay(input) {
|
|
|
30320
30565
|
}
|
|
30321
30566
|
);
|
|
30322
30567
|
if (synced.ok && Array.isArray(synced.body.commands)) {
|
|
30568
|
+
delay = baseInterval;
|
|
30323
30569
|
for (const command of synced.body.commands) {
|
|
30324
30570
|
applySiteCommand(input.host, command);
|
|
30325
30571
|
}
|
|
30572
|
+
} else {
|
|
30573
|
+
delay = Math.min(delay * 2, maxInterval);
|
|
30326
30574
|
}
|
|
30327
|
-
await sleep(
|
|
30575
|
+
await sleep(delay);
|
|
30328
30576
|
}
|
|
30329
30577
|
})();
|
|
30330
30578
|
void loop.catch(() => void 0);
|
|
30331
30579
|
return {
|
|
30332
30580
|
agentId,
|
|
30333
30581
|
origin,
|
|
30582
|
+
url: browserUrl,
|
|
30334
30583
|
async close() {
|
|
30335
30584
|
abort.abort();
|
|
30336
30585
|
}
|
|
@@ -30772,7 +31021,7 @@ async function startCritiqueCodeWebServer(input) {
|
|
|
30772
31021
|
return { kind: "kernel_required", limitation: error instanceof Error ? error.message : String(error) };
|
|
30773
31022
|
}
|
|
30774
31023
|
const repositoryRoot = await findRepositoryRoot(input.cwd);
|
|
30775
|
-
const token =
|
|
31024
|
+
const token = randomBytes3(18).toString("base64url");
|
|
30776
31025
|
const hub = new CritiqueCodeLineHub();
|
|
30777
31026
|
const pushLine = (line) => input.attach?.push(line) ?? hub.push(line);
|
|
30778
31027
|
const clients = /* @__PURE__ */ new Set();
|
|
@@ -30801,16 +31050,16 @@ async function startCritiqueCodeWebServer(input) {
|
|
|
30801
31050
|
let reviewModels = [...initialReviewModels];
|
|
30802
31051
|
let pendingExec;
|
|
30803
31052
|
const storeRoot = input.store_root ?? defaultCritiqueCodeStoreRoot(repositoryRoot);
|
|
30804
|
-
const chatsPath =
|
|
31053
|
+
const chatsPath = join22(storeRoot, "web-chats.json");
|
|
30805
31054
|
let chats = [{
|
|
30806
|
-
id:
|
|
31055
|
+
id: randomBytes3(6).toString("hex"),
|
|
30807
31056
|
title: "New session",
|
|
30808
31057
|
created_at: (input.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
|
|
30809
31058
|
events: []
|
|
30810
31059
|
}];
|
|
30811
31060
|
let activeId = chats[0].id;
|
|
30812
31061
|
try {
|
|
30813
|
-
const raw = JSON.parse(await
|
|
31062
|
+
const raw = JSON.parse(await readFile25(chatsPath, "utf8"));
|
|
30814
31063
|
if (Array.isArray(raw.chats) && raw.chats.length > 0) {
|
|
30815
31064
|
chats = raw.chats.map((chat) => ({
|
|
30816
31065
|
id: String(chat.id),
|
|
@@ -30825,7 +31074,7 @@ async function startCritiqueCodeWebServer(input) {
|
|
|
30825
31074
|
const sessionSummaries = () => chats.map((chat) => ({ id: chat.id, title: chat.title, created_at: chat.created_at }));
|
|
30826
31075
|
const activeChat = () => chats.find((chat) => chat.id === activeId) ?? chats[0];
|
|
30827
31076
|
const persistChats = () => {
|
|
30828
|
-
void
|
|
31077
|
+
void mkdir17(storeRoot, { recursive: true, mode: 448 }).then(() => writeFile16(
|
|
30829
31078
|
chatsPath,
|
|
30830
31079
|
`${JSON.stringify({ active_id: activeId, chats }, null, 2)}
|
|
30831
31080
|
`,
|
|
@@ -31013,7 +31262,7 @@ data: ${JSON.stringify(stamped)}
|
|
|
31013
31262
|
return "approve";
|
|
31014
31263
|
}
|
|
31015
31264
|
return new Promise((resolve14) => {
|
|
31016
|
-
const id4 =
|
|
31265
|
+
const id4 = randomBytes3(9).toString("hex");
|
|
31017
31266
|
const pending = { id: id4, purpose: request.purpose, preview: request.preview, resolve: resolve14 };
|
|
31018
31267
|
execs.set(id4, pending);
|
|
31019
31268
|
pendingExec = { id: id4, purpose: request.purpose, preview: request.preview };
|
|
@@ -31261,7 +31510,7 @@ exit ${code2 ?? "killed"}
|
|
|
31261
31510
|
}
|
|
31262
31511
|
if (req.method === "POST" && path2 === "/api/sessions") {
|
|
31263
31512
|
const chat = {
|
|
31264
|
-
id:
|
|
31513
|
+
id: randomBytes3(6).toString("hex"),
|
|
31265
31514
|
title: "New session",
|
|
31266
31515
|
created_at: (input.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
|
|
31267
31516
|
events: []
|
|
@@ -31277,7 +31526,7 @@ exit ${code2 ?? "killed"}
|
|
|
31277
31526
|
if (req.method === "POST" && path2 === "/api/sessions/fork") {
|
|
31278
31527
|
const source = activeChat();
|
|
31279
31528
|
const chat = {
|
|
31280
|
-
id:
|
|
31529
|
+
id: randomBytes3(6).toString("hex"),
|
|
31281
31530
|
title: `${source.title === "New session" ? "Fork" : source.title} \xB7 fork`,
|
|
31282
31531
|
created_at: (input.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
|
|
31283
31532
|
events: source.events.map((event) => ({ ...event }))
|
|
@@ -31432,7 +31681,8 @@ exit ${code2 ?? "killed"}
|
|
|
31432
31681
|
}
|
|
31433
31682
|
if (req.method === "POST" && (path2 === "/api/prompt" || path2 === "/api/command")) {
|
|
31434
31683
|
const body = await readJson(req);
|
|
31435
|
-
const
|
|
31684
|
+
const images = parseWebPromptImages(body.images);
|
|
31685
|
+
const text = String(body.text ?? body.prompt ?? "").trim() || (images.length > 0 ? "Look at the attached image." : "");
|
|
31436
31686
|
if (!text) {
|
|
31437
31687
|
send(res, 400, { error: "text required" });
|
|
31438
31688
|
return;
|
|
@@ -31486,7 +31736,12 @@ ${extras.join("\n\n")}` : text);
|
|
|
31486
31736
|
nameActiveChat(text);
|
|
31487
31737
|
emitGate();
|
|
31488
31738
|
}
|
|
31489
|
-
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
|
+
);
|
|
31490
31745
|
send(res, queued ? 202 : 409, { ok: queued });
|
|
31491
31746
|
return;
|
|
31492
31747
|
}
|
|
@@ -31857,15 +32112,16 @@ ${extras.join("\n\n")}` : text);
|
|
|
31857
32112
|
else siteRelay = startedSite;
|
|
31858
32113
|
}
|
|
31859
32114
|
}
|
|
31860
|
-
if (access3 === "pair") {
|
|
32115
|
+
if (access3 === "pair" || siteRelay) {
|
|
31861
32116
|
input.stderr.write(formatRemoteBanner({
|
|
31862
32117
|
repository_name: basename4(repositoryRoot),
|
|
31863
|
-
pin_display: pairing
|
|
32118
|
+
...pairing ? { pin_display: pairing.pin_display } : {},
|
|
31864
32119
|
urls: {
|
|
31865
32120
|
loopback: urls.loopback,
|
|
31866
32121
|
lan: urls.lan,
|
|
31867
32122
|
...urls.tunnel ? { tunnel: urls.tunnel } : {}
|
|
31868
32123
|
},
|
|
32124
|
+
...siteRelay ? { cloud_url: siteRelay.url } : {},
|
|
31869
32125
|
portals: connectedPortals
|
|
31870
32126
|
}));
|
|
31871
32127
|
} else {
|
|
@@ -32010,7 +32266,7 @@ Loopback only. The author session stays in this process.
|
|
|
32010
32266
|
...urls.lan.length > 0 ? { lan_urls: urls.lan } : {},
|
|
32011
32267
|
...urls.tunnel ? { tunnel_url: urls.tunnel } : {},
|
|
32012
32268
|
...connectedPortals.length > 0 ? { portals: connectedPortals } : {},
|
|
32013
|
-
...siteRelay ? { site: { agentId: siteRelay.agentId, origin: siteRelay.origin } } : {},
|
|
32269
|
+
...siteRelay ? { site: { agentId: siteRelay.agentId, origin: siteRelay.origin, url: siteRelay.url } } : {},
|
|
32014
32270
|
async close() {
|
|
32015
32271
|
hub.close();
|
|
32016
32272
|
for (const adapter of portalAdapters) await adapter.stop().catch(() => void 0);
|
|
@@ -32051,7 +32307,7 @@ Usage:
|
|
|
32051
32307
|
pnpm --filter @critiquedotsh/harness start
|
|
32052
32308
|
critique-code | critique-code chat [--intent <text>] [--models provider/model,...] [--cwd <dir>] [--store <dir>] [--voice] [--json]
|
|
32053
32309
|
critique-code web [--port <n>] [--cwd <dir>] [--store <dir>] [--models ...]
|
|
32054
|
-
critique-code remote [--
|
|
32310
|
+
critique-code remote [--lan] [--anywhere] [--slack] [--telegram] [--port <n>] [--cwd <dir>] [--store <dir>] [--models ...]
|
|
32055
32311
|
critique-code connect [CODE] [--port <n>] [--cwd <dir>]
|
|
32056
32312
|
critique-code slack [--port <n>] [--cwd <dir>]
|
|
32057
32313
|
critique-code telegram [--port <n>] [--cwd <dir>]
|
|
@@ -32079,7 +32335,7 @@ Interactive author commands:
|
|
|
32079
32335
|
/watch on Review on file save
|
|
32080
32336
|
/repair Verified repair of promoted findings (not auto-applied chatter)
|
|
32081
32337
|
/ship Review, then end if the controller allows
|
|
32082
|
-
/remote
|
|
32338
|
+
/remote Attach critique.sh/code to this laptop (Critique Remote)
|
|
32083
32339
|
/connect [CODE] Attach critique.sh/code to this laptop
|
|
32084
32340
|
/slack Attach Slack Socket Mode to this session
|
|
32085
32341
|
/telegram Attach a Telegram bot to this session
|
|
@@ -32093,7 +32349,7 @@ Interactive author commands:
|
|
|
32093
32349
|
|
|
32094
32350
|
Interactive TTY author sessions keep stdout quiet; pass --json for the session envelope.
|
|
32095
32351
|
\`critique-code web\` serves a loopback browser UI on 127.0.0.1. The author kernel still runs in this process.
|
|
32096
|
-
\`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.
|
|
32097
32353
|
\`critique-code connect [CODE]\` registers this PC on critique.sh/code. The website is a remote; the kernel stays here.
|
|
32098
32354
|
\`critique-code slack\` / \`critique-code telegram\` open outbound bots so you can DM the agent from those apps. The kernel stays here.
|
|
32099
32355
|
Other commands print JSON on stdout. Live chrome goes to stderr.
|
|
@@ -32177,6 +32433,8 @@ function parseInvocation(argv) {
|
|
|
32177
32433
|
repair: { type: "string" },
|
|
32178
32434
|
port: { type: "string" },
|
|
32179
32435
|
anywhere: { type: "boolean" },
|
|
32436
|
+
lan: { type: "boolean" },
|
|
32437
|
+
cloud: { type: "boolean" },
|
|
32180
32438
|
slack: { type: "boolean" },
|
|
32181
32439
|
telegram: { type: "boolean" },
|
|
32182
32440
|
pair: { type: "boolean" },
|
|
@@ -32315,9 +32573,11 @@ function parseInvocation(argv) {
|
|
|
32315
32573
|
const portals = [];
|
|
32316
32574
|
if (command === "slack" || parsed.values.slack) portals.push("slack");
|
|
32317
32575
|
if (command === "telegram" || parsed.values.telegram) portals.push("telegram");
|
|
32318
|
-
const
|
|
32576
|
+
const lan = Boolean(parsed.values.lan || parsed.values.pair);
|
|
32577
|
+
const access3 = lan ? "pair" : "loopback";
|
|
32319
32578
|
const offerCode = command === "connect" ? parsed.positionals[1]?.trim() : void 0;
|
|
32320
|
-
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;
|
|
32321
32581
|
const surface = command === "web" ? void 0 : command;
|
|
32322
32582
|
return {
|
|
32323
32583
|
command: "web",
|
|
@@ -32485,16 +32745,18 @@ ${helpText}`);
|
|
|
32485
32745
|
`);
|
|
32486
32746
|
return;
|
|
32487
32747
|
}
|
|
32748
|
+
const lan = kind === "remote" && options?.lan === true;
|
|
32488
32749
|
const started = await (io.web ?? startCritiqueCodeWebServer)({
|
|
32489
32750
|
cwd: invocation.cwd ?? io.cwd,
|
|
32490
32751
|
env: io.env ?? process.env,
|
|
32491
32752
|
stdout: io.stdout,
|
|
32492
32753
|
stderr: io.stderr,
|
|
32493
32754
|
open: false,
|
|
32494
|
-
access:
|
|
32755
|
+
access: lan ? "pair" : "loopback",
|
|
32495
32756
|
...options?.anywhere ? { anywhere: true } : {},
|
|
32496
32757
|
...kind === "slack" ? { portals: ["slack"] } : {},
|
|
32497
32758
|
...kind === "telegram" ? { portals: ["telegram"] } : {},
|
|
32759
|
+
...kind === "remote" && !lan ? { site: true } : {},
|
|
32498
32760
|
...kind === "site" ? { site: options?.offerCode ? { offerCode: options.offerCode } : true } : {},
|
|
32499
32761
|
...inject ? { attach: { push: inject } } : {},
|
|
32500
32762
|
...io.driver ? { driver: io.driver } : {},
|
|
@@ -32510,8 +32772,8 @@ ${helpText}`);
|
|
|
32510
32772
|
return;
|
|
32511
32773
|
}
|
|
32512
32774
|
if ("url" in started) {
|
|
32513
|
-
io.stderr.write(kind === "remote" ? `Phone pairing is up. PIN is in the banner above. Kernel stays on this laptop.
|
|
32514
|
-
` : 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.
|
|
32515
32777
|
` : `${kind} is attached. DM the bot. Kernel stays on this laptop.
|
|
32516
32778
|
`);
|
|
32517
32779
|
}
|