@rryando/arcs 5.1.0 → 5.2.0
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/README.md +1 -1
- package/dist/cli/arcs-orchestrate.d.ts +1 -1
- package/dist/cli/arcs-orchestrate.d.ts.map +1 -1
- package/dist/cli/commands/proposal-doc.js +76 -58
- package/dist/cli/commands/proposal-doc.js.map +1 -1
- package/dist/cli/config.d.ts +19 -9
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +18 -5
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/instructions.d.ts +3 -3
- package/dist/cli/instructions.d.ts.map +1 -1
- package/dist/cli/instructions.js +10 -2
- package/dist/cli/instructions.js.map +1 -1
- package/dist/cli/orchestrator-shared-blocks.d.ts +1 -1
- package/dist/cli/orchestrator-shared-blocks.d.ts.map +1 -1
- package/dist/cli/orchestrator-shared-blocks.js +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +64 -13
- package/dist/cli/setup.js.map +1 -1
- package/dist/utils/json-schemas.d.ts +23 -0
- package/dist/utils/json-schemas.d.ts.map +1 -1
- package/dist/utils/json-schemas.js +7 -0
- package/dist/utils/json-schemas.js.map +1 -1
- package/dist/utils/project-resolver.d.ts.map +1 -1
- package/dist/utils/project-resolver.js +9 -2
- package/dist/utils/project-resolver.js.map +1 -1
- package/dist/web-client/assets/{GraphCanvas-BYZE4sO9.js → GraphCanvas-DvTmx2os.js} +1 -1
- package/dist/web-client/assets/{MarkdownEditor-BKx6M1cw.js → MarkdownEditor-B8j_5lK7.js} +1 -1
- package/dist/web-client/assets/{abnfDiagram-VRR7QNED-D4kt0l2y.js → abnfDiagram-VRR7QNED-DZ5c8NM5.js} +1 -1
- package/dist/web-client/assets/architecture-TIHT7OUA-B6H7ClR9.js +1 -0
- package/dist/web-client/assets/{architectureDiagram-ZJ3FMSHR-bu29SJFS.js → architectureDiagram-ZJ3FMSHR-DeNroB33.js} +1 -1
- package/dist/web-client/assets/{blockDiagram-677ZJIJ3-hsu7mXKw.js → blockDiagram-677ZJIJ3-C92i1GHh.js} +1 -1
- package/dist/web-client/assets/{c4Diagram-LMCZKHZV-DMllRlT_.js → c4Diagram-LMCZKHZV-BniYzyYJ.js} +1 -1
- package/dist/web-client/assets/channel-CinHQ6_V.js +1 -0
- package/dist/web-client/assets/{chunk-32BRIVSS-BSzwj5eM.js → chunk-32BRIVSS-DXA4fMwe.js} +1 -1
- package/dist/web-client/assets/{chunk-52WLFC77-RDdZn6yY.js → chunk-52WLFC77-DxLpDT5g.js} +1 -1
- package/dist/web-client/assets/{chunk-C7G6YPKG-DQr--txT.js → chunk-C7G6YPKG-DC22BvA6.js} +1 -1
- package/dist/web-client/assets/{chunk-EX3LRPZG-Bb8nc4z4.js → chunk-EX3LRPZG-CP5bMsNz.js} +1 -1
- package/dist/web-client/assets/{chunk-FWX5IMBZ-QvBpOcOg.js → chunk-FWX5IMBZ-CRhTkdyH.js} +2 -2
- package/dist/web-client/assets/{chunk-HOUHSVGY-B0mX_yjc.js → chunk-HOUHSVGY-BL8xdKlN.js} +1 -1
- package/dist/web-client/assets/{chunk-ICXQ74PX-BmJSQqOH.js → chunk-ICXQ74PX-B7Ur00R9.js} +1 -1
- package/dist/web-client/assets/{chunk-MOJQB5TN-BrEI4GGn.js → chunk-MOJQB5TN-D9EnTuIj.js} +1 -1
- package/dist/web-client/assets/{chunk-OGEWGWER-CrqDPOWP.js → chunk-OGEWGWER-Dr-xsHrU.js} +1 -1
- package/dist/web-client/assets/{chunk-PUDLZKDR-DfPKldpG.js → chunk-PUDLZKDR-BIrspPOB.js} +1 -1
- package/dist/web-client/assets/{chunk-Q4XR5HBZ-ekATI9aV.js → chunk-Q4XR5HBZ-Dfip_4XA.js} +1 -1
- package/dist/web-client/assets/{chunk-V7JOEXUC-C5APsP1t.js → chunk-V7JOEXUC-CWqwzV_g.js} +1 -1
- package/dist/web-client/assets/{chunk-VAUOI2AC-BhfSWJZI.js → chunk-VAUOI2AC-EosDVEFn.js} +1 -1
- package/dist/web-client/assets/{chunk-VR4S4FIN-BGa-44J7.js → chunk-VR4S4FIN-DnMox7F5.js} +1 -1
- package/dist/web-client/assets/{chunk-WYO6CB5R-By1K0guW.js → chunk-WYO6CB5R-B3xja0Q5.js} +1 -1
- package/dist/web-client/assets/{chunk-ZGVPDNZ5-Vnzpc76F.js → chunk-ZGVPDNZ5-BGoIOVsc.js} +1 -1
- package/dist/web-client/assets/classDiagram-OUVF2IWQ-D_fljwRI.js +1 -0
- package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-D_fljwRI.js +1 -0
- package/dist/web-client/assets/{cynefin-VYW2F7L2-C6MOMOOz.js → cynefin-VYW2F7L2-BlBnSViH.js} +1 -1
- package/dist/web-client/assets/{cynefinDiagram-TSTJHNR4-Cseyu79b.js → cynefinDiagram-TSTJHNR4-jRcAddSh.js} +1 -1
- package/dist/web-client/assets/{dagre-VKFMJZFB-CQJlIuNh.js → dagre-VKFMJZFB-D4elj7jV.js} +1 -1
- package/dist/web-client/assets/{diagram-FQU43EPY-DpqDxhq4.js → diagram-FQU43EPY-D7OKzbLh.js} +1 -1
- package/dist/web-client/assets/{diagram-G47NLZAW-C11fYYaF.js → diagram-G47NLZAW-DBF9p-RV.js} +1 -1
- package/dist/web-client/assets/{diagram-NH7WQ7WH-BiG-uRAF.js → diagram-NH7WQ7WH-CpE02PRM.js} +1 -1
- package/dist/web-client/assets/{diagram-OA4YK3LP-CIXWWjq-.js → diagram-OA4YK3LP-BdJ1lOcZ.js} +1 -1
- package/dist/web-client/assets/{diagram-WEI45ONY-C3OgIWu9.js → diagram-WEI45ONY-BpPxpOcu.js} +1 -1
- package/dist/web-client/assets/{ebnfDiagram-CCIWWBDH-BHF_NA3_.js → ebnfDiagram-CCIWWBDH-DLKdgImF.js} +1 -1
- package/dist/web-client/assets/{erDiagram-Q63AITRT-CUOJCrLy.js → erDiagram-Q63AITRT-c0bbf0vk.js} +1 -1
- package/dist/web-client/assets/eventmodeling-45OFAUF4-DT6B-Tvn.js +1 -0
- package/dist/web-client/assets/flowDiagram-23GEKE2U-fbZofWHf.js +1 -0
- package/dist/web-client/assets/{ganttDiagram-NO4QXBWP-D_4BMJ-g.js → ganttDiagram-NO4QXBWP-Ynj8Qkax.js} +1 -1
- package/dist/web-client/assets/{gitGraph-TEB2WS4Q-CBuaZBId.js → gitGraph-TEB2WS4Q-j-MdxZrn.js} +1 -1
- package/dist/web-client/assets/{gitGraphDiagram-IHSO6WYX-BbztsGuO.js → gitGraphDiagram-IHSO6WYX-SaPe2Npn.js} +1 -1
- package/dist/web-client/assets/index-C1WQ25Ow.js +60 -0
- package/dist/web-client/assets/index-CHdOvANQ.css +2 -0
- package/dist/web-client/assets/{info-DKCQHKI2-Bzi0Xjro.js → info-DKCQHKI2-DzsnPugh.js} +1 -1
- package/dist/web-client/assets/{infoDiagram-FWYZ7A6U-BkeEKcr0.js → infoDiagram-FWYZ7A6U-e6BJvSRj.js} +1 -1
- package/dist/web-client/assets/{ishikawaDiagram-FXEZZL3T-CVusWu0p.js → ishikawaDiagram-FXEZZL3T-DI1KDN2v.js} +1 -1
- package/dist/web-client/assets/{journeyDiagram-5HDEW3XC-BUxu71zw.js → journeyDiagram-5HDEW3XC-BQbFOIm6.js} +1 -1
- package/dist/web-client/assets/{kanban-definition-HUTT4EX6-BE8Hv4Kd.js → kanban-definition-HUTT4EX6-D5DV7Dh0.js} +1 -1
- package/dist/web-client/assets/{line-CiAoINJS.js → line-D_qHyqs1.js} +1 -1
- package/dist/web-client/assets/{mermaid-parser.core-BW47khiS.js → mermaid-parser.core-VzGX5B89.js} +3 -3
- package/dist/web-client/assets/{mermaid.core-DP--Jl9R.js → mermaid.core-BqWcehVs.js} +3 -3
- package/dist/web-client/assets/{mindmap-definition-LN4V7U3C-CvWJUqdq.js → mindmap-definition-LN4V7U3C-CcZZrFcy.js} +1 -1
- package/dist/web-client/assets/{packet-7NZHBO7P-XtzX9SaQ.js → packet-7NZHBO7P-DWMuocpD.js} +1 -1
- package/dist/web-client/assets/{pegDiagram-2B236MQR-XNo0K1ct.js → pegDiagram-2B236MQR-CQfp4S-y.js} +1 -1
- package/dist/web-client/assets/{pie-RZYD4A2V-B1eUd9yt.js → pie-RZYD4A2V-BlI6y28n.js} +1 -1
- package/dist/web-client/assets/{pieDiagram-ENE6RG2P-CRSb5z-4.js → pieDiagram-ENE6RG2P-DEsRhIVS.js} +1 -1
- package/dist/web-client/assets/{quadrantDiagram-ABIIQ3AL-DziMaQxE.js → quadrantDiagram-ABIIQ3AL-BZCSbtlm.js} +1 -1
- package/dist/web-client/assets/{radar-I7S5WNFK-BpRqZH2g.js → radar-I7S5WNFK-DlwfjSpa.js} +1 -1
- package/dist/web-client/assets/{railroad-3IZDKUUU-FDIHW04k.js → railroad-3IZDKUUU-Be-bZpf0.js} +1 -1
- package/dist/web-client/assets/railroad-abnf-AHOZXSZD-C5-D4PxJ.js +1 -0
- package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-pJcCXE74.js +1 -0
- package/dist/web-client/assets/railroad-peg-LSFZ7HO6-B33ruY8f.js +1 -0
- package/dist/web-client/assets/{railroadDiagram-RFXS5EU6-Cs7EVBaz.js → railroadDiagram-RFXS5EU6-ClVubHv1.js} +1 -1
- package/dist/web-client/assets/{requirementDiagram-TGXJPOKE-B9_Lj1ga.js → requirementDiagram-TGXJPOKE-swYyFYJk.js} +1 -1
- package/dist/web-client/assets/{sankeyDiagram-HTMAVEWB-DuTJTiy0.js → sankeyDiagram-HTMAVEWB-LAu1XR2n.js} +1 -1
- package/dist/web-client/assets/{sequenceDiagram-DBY2YBRQ-vOCU5UoE.js → sequenceDiagram-DBY2YBRQ-XvIU8hX9.js} +1 -1
- package/dist/web-client/assets/{stateDiagram-2N3HPSRC-rxAnfzWn.js → stateDiagram-2N3HPSRC-C3nbJ1dX.js} +1 -1
- package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-Da0ex-S_.js +1 -0
- package/dist/web-client/assets/{swimlanes-5IMT3BWC-gdVZUnPe.js → swimlanes-5IMT3BWC-BF5fFeNe.js} +1 -1
- package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-cc5MstHU.js +8 -0
- package/dist/web-client/assets/{timeline-definition-FHXFAJF6-Do68JyGy.js → timeline-definition-FHXFAJF6-CjK82kFp.js} +1 -1
- package/dist/web-client/assets/{treeView-QDETBFTQ-CdZkmg80.js → treeView-QDETBFTQ-DBRGCYnY.js} +1 -1
- package/dist/web-client/assets/{treemap-6X3UGDF4-ub54fmpW.js → treemap-6X3UGDF4-BIexMw3j.js} +1 -1
- package/dist/web-client/assets/{vennDiagram-L72KCM5P-D-r8NBEp.js → vennDiagram-L72KCM5P-DOjvh0XG.js} +1 -1
- package/dist/web-client/assets/{wardley-OPB4EBWU-CTleH1-J.js → wardley-OPB4EBWU-Dxw6mW95.js} +1 -1
- package/dist/web-client/assets/{wardleyDiagram-EHGQE667-BU8Kw39F.js → wardleyDiagram-EHGQE667-D1A7JTB_.js} +1 -1
- package/dist/web-client/assets/{xychartDiagram-FW5EYKEG-CfNnag6i.js → xychartDiagram-FW5EYKEG-CxvobQJD.js} +1 -1
- package/dist/web-client/index.html +2 -2
- package/dist/web-server/app.d.ts.map +1 -1
- package/dist/web-server/app.js +2 -0
- package/dist/web-server/app.js.map +1 -1
- package/dist/web-server/respond.d.ts.map +1 -1
- package/dist/web-server/respond.js +5 -1
- package/dist/web-server/respond.js.map +1 -1
- package/dist/web-server/routes/projects.d.ts.map +1 -1
- package/dist/web-server/routes/projects.js +10 -2
- package/dist/web-server/routes/projects.js.map +1 -1
- package/dist/web-server/routes/proposal-docs.d.ts +18 -0
- package/dist/web-server/routes/proposal-docs.d.ts.map +1 -0
- package/dist/web-server/routes/proposal-docs.js +208 -0
- package/dist/web-server/routes/proposal-docs.js.map +1 -0
- package/opencode/arcs/prompts/arcs-orchestrate-caveman.txt +1 -1
- package/opencode/arcs/prompts/arcs-orchestrate.txt +1 -1
- package/opencode/arcs/skills/writing-proposals/SKILL.md +6 -3
- package/package.json +1 -1
- package/scripts/deploy-claudecode-bundle.mjs +1 -1
- package/dist/web-client/assets/architecture-TIHT7OUA-CIdGE6VO.js +0 -1
- package/dist/web-client/assets/channel-CBg-s-ZD.js +0 -1
- package/dist/web-client/assets/classDiagram-OUVF2IWQ-ciwDjhUR.js +0 -1
- package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-ciwDjhUR.js +0 -1
- package/dist/web-client/assets/eventmodeling-45OFAUF4-DxfboL1J.js +0 -1
- package/dist/web-client/assets/flowDiagram-23GEKE2U-C3NzpTtI.js +0 -1
- package/dist/web-client/assets/index-B1KVIr80.css +0 -2
- package/dist/web-client/assets/index-BWd2fBNL.js +0 -60
- package/dist/web-client/assets/railroad-abnf-AHOZXSZD-BKj6JAhH.js +0 -1
- package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-ChDM1OBv.js +0 -1
- package/dist/web-client/assets/railroad-peg-LSFZ7HO6-DvwA2e0i.js +0 -1
- package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-B3EvQPEe.js +0 -1
- package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-WcOXuCPg.js +0 -8
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proposal-doc routes: human-in-the-loop design proposal documents.
|
|
3
|
+
*
|
|
4
|
+
* Docs live in the project data dir under proposals/ (data-dir plane, never
|
|
5
|
+
* the workspace), cohabiting with the codegraph proposal queue's codegraph.json
|
|
6
|
+
* — every scan is extension-scoped (*.proposal.md / *.accepted.md) so the
|
|
7
|
+
* queue file never leaks into listings. Read semantics mirror the
|
|
8
|
+
* `proposal-doc` CLI commands; writes go through the web server's lock-safe
|
|
9
|
+
* storage helpers.
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync } from "node:fs";
|
|
12
|
+
import { mkdir, readdir, readFile, rename, stat } from "node:fs/promises";
|
|
13
|
+
import { basename, join, resolve } from "node:path";
|
|
14
|
+
import { Hono } from "hono";
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
import { DagError } from "../../utils/errors.js";
|
|
17
|
+
import { withLock } from "../../utils/file-lock.js";
|
|
18
|
+
import { createPlan, readPlanIndex } from "../../utils/plan-store.js";
|
|
19
|
+
import { normalizeIdentifier } from "../../utils/slug.js";
|
|
20
|
+
import { parseBody, requireProjectDir, respond } from "../respond.js";
|
|
21
|
+
import { writeTextLocked } from "../storage.js";
|
|
22
|
+
export const proposalDocsRoute = new Hono();
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Helpers
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
const PROPOSALS_DIR = "proposals";
|
|
27
|
+
const PROMOTE_LOCK = ".proposal-doc-promotion";
|
|
28
|
+
function proposalDocsDir(projectDir) {
|
|
29
|
+
return resolve(projectDir, PROPOSALS_DIR);
|
|
30
|
+
}
|
|
31
|
+
function proposalDocPendingPath(projectDir, id) {
|
|
32
|
+
return resolve(proposalDocsDir(projectDir), `${id}.proposal.md`);
|
|
33
|
+
}
|
|
34
|
+
function proposalDocAcceptedPath(projectDir, id) {
|
|
35
|
+
return resolve(proposalDocsDir(projectDir), `${id}.accepted.md`);
|
|
36
|
+
}
|
|
37
|
+
/** Infer the proposal title from the first `# ` heading, falling back to the id. */
|
|
38
|
+
function deriveTitle(body, fallbackId) {
|
|
39
|
+
const titleLine = body.split("\n").find((line) => line.startsWith("# "));
|
|
40
|
+
return titleLine ? titleLine.replace(/^#\s+/, "").trim() : fallbackId;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Doc ids are filename stems; they must be slugs so a crafted :id cannot
|
|
44
|
+
* escape proposals/ via path traversal.
|
|
45
|
+
*/
|
|
46
|
+
function assertDocId(id) {
|
|
47
|
+
if (!id || normalizeIdentifier(id) !== id) {
|
|
48
|
+
throw new DagError("INVALID_DOC_ID", `Invalid proposal doc id "${id}"`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Directory scan tolerating a missing proposals/ dir; callers filter by suffix. */
|
|
52
|
+
async function readdirProposalFiles(projectDir) {
|
|
53
|
+
try {
|
|
54
|
+
return await readdir(proposalDocsDir(projectDir));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Pending (*.proposal.md) doc count via the same extension-scoped scan the
|
|
62
|
+
* list route uses. Shared with routes/projects.ts for counts.proposalDocs.
|
|
63
|
+
*/
|
|
64
|
+
export async function countPendingProposalDocs(projectDir) {
|
|
65
|
+
return (await readdirProposalFiles(projectDir)).filter((f) => f.endsWith(".proposal.md")).length;
|
|
66
|
+
}
|
|
67
|
+
proposalDocsRoute.get("/api/p/:slug/proposal-docs", async (c) => respond(c, async () => {
|
|
68
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
69
|
+
const files = (await readdirProposalFiles(projectDir)).sort();
|
|
70
|
+
const acceptedCount = files.filter((f) => f.endsWith(".accepted.md")).length;
|
|
71
|
+
// Accepted docs are promoted — visible via their plan — so only pending
|
|
72
|
+
// docs are listed; accepted ones surface as a count.
|
|
73
|
+
const proposalDocs = await Promise.all(files
|
|
74
|
+
.filter((f) => f.endsWith(".proposal.md"))
|
|
75
|
+
.map(async (file) => {
|
|
76
|
+
const id = basename(file, ".proposal.md");
|
|
77
|
+
const filePath = proposalDocPendingPath(projectDir, id);
|
|
78
|
+
const [body, updatedAt] = await Promise.all([
|
|
79
|
+
readFile(filePath, "utf-8").catch(() => ""),
|
|
80
|
+
stat(filePath)
|
|
81
|
+
.then((s) => s.mtime.toISOString())
|
|
82
|
+
.catch(() => null),
|
|
83
|
+
]);
|
|
84
|
+
return {
|
|
85
|
+
id,
|
|
86
|
+
title: deriveTitle(body, id),
|
|
87
|
+
status: "pending",
|
|
88
|
+
path: `proposals/${file}`,
|
|
89
|
+
updatedAt,
|
|
90
|
+
};
|
|
91
|
+
}));
|
|
92
|
+
return {
|
|
93
|
+
proposalDocs,
|
|
94
|
+
counts: { pending: proposalDocs.length, accepted: acceptedCount },
|
|
95
|
+
};
|
|
96
|
+
}));
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// GET /api/p/:slug/proposal-docs/:id — doc body with pending → accepted fallback
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
proposalDocsRoute.get("/api/p/:slug/proposal-docs/:id", async (c) => respond(c, async () => {
|
|
101
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
102
|
+
const id = c.req.param("id");
|
|
103
|
+
assertDocId(id);
|
|
104
|
+
// Same .proposal.md → .accepted.md fallback as the CLI get command.
|
|
105
|
+
let filePath = proposalDocPendingPath(projectDir, id);
|
|
106
|
+
let status = "pending";
|
|
107
|
+
if (!existsSync(filePath)) {
|
|
108
|
+
filePath = proposalDocAcceptedPath(projectDir, id);
|
|
109
|
+
status = "accepted";
|
|
110
|
+
if (!existsSync(filePath)) {
|
|
111
|
+
throw new DagError("ENTITY_NOT_FOUND", `Proposal doc not found: ${id} (tried .proposal.md and .accepted.md)`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const [body, stats] = await Promise.all([readFile(filePath, "utf-8"), stat(filePath)]);
|
|
115
|
+
return {
|
|
116
|
+
id,
|
|
117
|
+
status,
|
|
118
|
+
path: status === "pending" ? `proposals/${id}.proposal.md` : `proposals/${id}.accepted.md`,
|
|
119
|
+
title: deriveTitle(body, id),
|
|
120
|
+
body,
|
|
121
|
+
updatedAt: stats.mtime.toISOString(),
|
|
122
|
+
};
|
|
123
|
+
}));
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// PUT /api/p/:slug/proposal-docs/:id — replace the body of a PENDING doc
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
const updateProposalDocSchema = z.object({ content: z.string() });
|
|
128
|
+
proposalDocsRoute.put("/api/p/:slug/proposal-docs/:id", async (c) => respond(c, async () => {
|
|
129
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
130
|
+
const id = c.req.param("id");
|
|
131
|
+
assertDocId(id);
|
|
132
|
+
const { content } = await parseBody(c, updateProposalDocSchema);
|
|
133
|
+
const pendingPath = proposalDocPendingPath(projectDir, id);
|
|
134
|
+
if (!existsSync(pendingPath) && existsSync(proposalDocAcceptedPath(projectDir, id))) {
|
|
135
|
+
throw new DagError("ENTITY_NOT_FOUND", `Proposal doc "${id}" was already promoted; accepted proposal docs are read-only.`);
|
|
136
|
+
}
|
|
137
|
+
// Writes only ever hit the pending path; the proposals dir is created on
|
|
138
|
+
// first save so a brand-new id upserts cleanly.
|
|
139
|
+
await mkdir(proposalDocsDir(projectDir), { recursive: true });
|
|
140
|
+
await writeTextLocked(pendingPath, content);
|
|
141
|
+
return { id, status: "pending", path: `proposals/${id}.proposal.md`, updated: true };
|
|
142
|
+
}));
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
// POST /api/p/:slug/proposal-docs/:id/promote — rename + plan creation
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
proposalDocsRoute.post("/api/p/:slug/proposal-docs/:id/promote", async (c) => respond(c, async () => {
|
|
147
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
148
|
+
const id = c.req.param("id");
|
|
149
|
+
assertDocId(id);
|
|
150
|
+
return withLock(join(projectDir, PROMOTE_LOCK), async () => {
|
|
151
|
+
const pendingPath = proposalDocPendingPath(projectDir, id);
|
|
152
|
+
const acceptedPath = proposalDocAcceptedPath(projectDir, id);
|
|
153
|
+
let body;
|
|
154
|
+
let recovered = false;
|
|
155
|
+
if (existsSync(pendingPath)) {
|
|
156
|
+
body = await readFile(pendingPath, "utf-8");
|
|
157
|
+
}
|
|
158
|
+
else if (existsSync(acceptedPath)) {
|
|
159
|
+
// Crash recovery: the rename completed but plan creation never did.
|
|
160
|
+
// Re-run from the accepted body unless its plan already exists.
|
|
161
|
+
const acceptedBody = await readFile(acceptedPath, "utf-8");
|
|
162
|
+
const derivedPlanId = normalizeIdentifier(deriveTitle(acceptedBody, id));
|
|
163
|
+
const { plans } = await readPlanIndex(projectDir);
|
|
164
|
+
if (plans.some((p) => p.id === derivedPlanId)) {
|
|
165
|
+
throw new DagError("PLAN_CONFLICT", `Plan "${derivedPlanId}" already exists; proposal doc "${id}" is already promoted.`);
|
|
166
|
+
}
|
|
167
|
+
body = acceptedBody;
|
|
168
|
+
recovered = true;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
throw new DagError("ENTITY_NOT_FOUND", `Proposal doc not found: ${id} (tried .proposal.md and .accepted.md)`);
|
|
172
|
+
}
|
|
173
|
+
const title = deriveTitle(body, id);
|
|
174
|
+
const planId = normalizeIdentifier(title);
|
|
175
|
+
if (!recovered) {
|
|
176
|
+
// Conflict-check BEFORE the rename so a collision leaves nothing to
|
|
177
|
+
// roll back; createPlan re-checks under its own lock either way.
|
|
178
|
+
const { plans } = await readPlanIndex(projectDir);
|
|
179
|
+
if (plans.some((p) => p.id === planId)) {
|
|
180
|
+
throw new DagError("PLAN_CONFLICT", `Plan "${planId}" already exists; promoting "${id}" would collide with it.`);
|
|
181
|
+
}
|
|
182
|
+
await rename(pendingPath, acceptedPath);
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
const plan = await createPlan(projectDir, {
|
|
186
|
+
id: planId,
|
|
187
|
+
title,
|
|
188
|
+
status: "proposed",
|
|
189
|
+
keywords: [],
|
|
190
|
+
content: body,
|
|
191
|
+
});
|
|
192
|
+
return {
|
|
193
|
+
promoted: true,
|
|
194
|
+
plan,
|
|
195
|
+
docPath: `proposals/${id}.accepted.md`,
|
|
196
|
+
...(recovered && { recovered: true }),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
// Plan creation failed: roll the rename back so the doc stays pending.
|
|
201
|
+
if (!recovered) {
|
|
202
|
+
await rename(acceptedPath, pendingPath).catch(() => { });
|
|
203
|
+
}
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}));
|
|
208
|
+
//# sourceMappingURL=proposal-docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposal-docs.js","sourceRoot":"","sources":["../../../src/web-server/routes/proposal-docs.ts"],"names":[],"mappings":"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"}
|
|
@@ -81,7 +81,7 @@ Available skills: `implementation`, `test-driven-development`, `systematic-debug
|
|
|
81
81
|
|
|
82
82
|
## Design, Proposals, and Plans
|
|
83
83
|
|
|
84
|
-
For architecture-changing, large-feature, or cross-cutting work, delegate the proposal doc to `tech-architect` with the `writing-proposals` skill, stored in `
|
|
84
|
+
For architecture-changing, large-feature, or cross-cutting work, delegate the proposal doc to `tech-architect` with the `writing-proposals` skill, stored in the data dir under `projects/<slug>/proposals/`, not the workspace. Iterate with the user until approval, then delegate plan creation to `arcs-docs` with the `writing-plans` skill.
|
|
85
85
|
|
|
86
86
|
For broad multi-step or explicitly requested plans, delegate plan creation directly. Resolve material choices with the user; do not ask about details that repository evidence or convention settles.
|
|
87
87
|
|
|
@@ -75,7 +75,7 @@ Available skills: `implementation`, `test-driven-development`, `systematic-debug
|
|
|
75
75
|
|
|
76
76
|
## Design, Proposals, and Plans
|
|
77
77
|
|
|
78
|
-
For architecture-changing, large-feature, or cross-cutting work, delegate the proposal doc to `tech-architect` with the `writing-proposals` skill, stored in `
|
|
78
|
+
For architecture-changing, large-feature, or cross-cutting work, delegate the proposal doc to `tech-architect` with the `writing-proposals` skill, stored in the data dir under `projects/<slug>/proposals/`, not the workspace. Iterate with the user until approval, then delegate plan creation to `arcs-docs` with the `writing-plans` skill.
|
|
79
79
|
|
|
80
80
|
For broad multi-step or explicitly requested plans, delegate plan creation directly. Resolve material choices with the user; do not ask about details that repository evidence or convention settles.
|
|
81
81
|
|
|
@@ -28,9 +28,12 @@ the handoff to stage two, then delegates explicitly.
|
|
|
28
28
|
|
|
29
29
|
## CLI
|
|
30
30
|
|
|
31
|
-
All proposal doc operations use the `arcs proposal-doc` command group
|
|
31
|
+
All proposal doc operations use the `arcs proposal-doc` command group. Documents
|
|
32
|
+
are stored in the ARCS data dir under `projects/<slug>/proposals/` (not the
|
|
33
|
+
workspace); workspace `docs/proposals/` files are ignored by tooling (no
|
|
34
|
+
migration):
|
|
32
35
|
|
|
33
|
-
- `arcs proposal-doc create <slug> "<title>"` — scaffold `
|
|
36
|
+
- `arcs proposal-doc create <slug> "<title>"` — scaffold `proposals/<id>.proposal.md` in the project data dir
|
|
34
37
|
- `arcs proposal-doc list <slug>` — list pending proposals (both `.proposal.md` files)
|
|
35
38
|
- `arcs proposal-doc get <slug> <id>` — view body text of a proposal (pending or accepted)
|
|
36
39
|
- `arcs proposal-doc edit <slug> <id> --body="..."` — replace body text
|
|
@@ -43,7 +46,7 @@ All proposal doc operations use the `arcs proposal-doc` command group:
|
|
|
43
46
|
(`arcs brief`, knowledge search). A proposal grounded only in the request
|
|
44
47
|
text is a guess, not a proposal.
|
|
45
48
|
2. **Draft** with `arcs proposal-doc create <slug> "<title>"`. This scaffolds
|
|
46
|
-
`
|
|
49
|
+
`proposals/<kebab-id>.proposal.md` under the project's data dir with the required sections:
|
|
47
50
|
- **Goal** — the outcome in one paragraph.
|
|
48
51
|
- **Motivation / non-goals** — why now, what is explicitly out of scope.
|
|
49
52
|
- **Current state** — how it works today, with file/symbol references.
|
package/package.json
CHANGED
|
@@ -106,7 +106,7 @@ function resolveBundlePromptPath(value) {
|
|
|
106
106
|
// ---------------------------------------------------------------------------
|
|
107
107
|
// Model tier configuration
|
|
108
108
|
// ---------------------------------------------------------------------------
|
|
109
|
-
// Env vars: DEPLOY_MODEL_HEAVY, DEPLOY_MODEL_STANDARD, DEPLOY_MODEL_LIGHT
|
|
109
|
+
// Env vars: DEPLOY_MODEL_HEAVY, DEPLOY_MODEL_STANDARD, DEPLOY_MODEL_LIGHT.
|
|
110
110
|
// Each defaults to "inherit" if unset.
|
|
111
111
|
const tierModels = {
|
|
112
112
|
heavy: process.env.DEPLOY_MODEL_HEAVY || "inherit",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./chunk-KEIR6QF5-DEvma7oi.js";import{M as e}from"./mermaid-parser.core-BW47khiS.js";export{e as createArchitectureServices};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{at as e,it as t}from"./chunk-WYO6CB5R-By1K0guW.js";var n=(n,r)=>e.lang.round(t.parse(n)[r]);export{n as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./src-oBChb5qS.js";import"./chunk-WYO6CB5R-By1K0guW.js";import"./chunk-ICXQ74PX-BmJSQqOH.js";import"./chunk-HOUHSVGY-B0mX_yjc.js";import"./chunk-Q4XR5HBZ-ekATI9aV.js";import"./chunk-7BUUIJ7U-Bb538aSH.js";import"./chunk-OGEWGWER-CrqDPOWP.js";import"./chunk-32BRIVSS-BSzwj5eM.js";import"./chunk-XXDRQBXY-BvKO0v-W.js";import"./chunk-VR4S4FIN-BGa-44J7.js";import"./chunk-C7G6YPKG-DQr--txT.js";import"./chunk-ZGVPDNZ5-Vnzpc76F.js";import"./chunk-52WLFC77-RDdZn6yY.js";import"./chunk-FWX5IMBZ-QvBpOcOg.js";import{i as t,n,r,t as i}from"./chunk-V7JOEXUC-C5APsP1t.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./src-oBChb5qS.js";import"./chunk-WYO6CB5R-By1K0guW.js";import"./chunk-ICXQ74PX-BmJSQqOH.js";import"./chunk-HOUHSVGY-B0mX_yjc.js";import"./chunk-Q4XR5HBZ-ekATI9aV.js";import"./chunk-7BUUIJ7U-Bb538aSH.js";import"./chunk-OGEWGWER-CrqDPOWP.js";import"./chunk-32BRIVSS-BSzwj5eM.js";import"./chunk-XXDRQBXY-BvKO0v-W.js";import"./chunk-VR4S4FIN-BGa-44J7.js";import"./chunk-C7G6YPKG-DQr--txT.js";import"./chunk-ZGVPDNZ5-Vnzpc76F.js";import"./chunk-52WLFC77-RDdZn6yY.js";import"./chunk-FWX5IMBZ-QvBpOcOg.js";import{i as t,n,r,t as i}from"./chunk-V7JOEXUC-C5APsP1t.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./chunk-KEIR6QF5-DEvma7oi.js";import{O as e}from"./mermaid-parser.core-BW47khiS.js";export{e as createEventModelingServices};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./src-oBChb5qS.js";import"./chunk-WYO6CB5R-By1K0guW.js";import"./chunk-ICXQ74PX-BmJSQqOH.js";import"./chunk-HOUHSVGY-B0mX_yjc.js";import"./chunk-Q4XR5HBZ-ekATI9aV.js";import"./chunk-7BUUIJ7U-Bb538aSH.js";import"./chunk-OGEWGWER-CrqDPOWP.js";import"./chunk-32BRIVSS-BSzwj5eM.js";import"./chunk-XXDRQBXY-BvKO0v-W.js";import"./chunk-VR4S4FIN-BGa-44J7.js";import"./chunk-C7G6YPKG-DQr--txT.js";import"./chunk-ZGVPDNZ5-Vnzpc76F.js";import"./chunk-52WLFC77-RDdZn6yY.js";import"./chunk-FWX5IMBZ-QvBpOcOg.js";import"./chunk-ZIRB5QZD-BpeS1aZ7.js";import{n as e}from"./chunk-PUDLZKDR-DfPKldpG.js";export{e as diagram};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:"JetBrains Mono Variable", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--color-emerald-500:oklch(69.6% .17 162.48);--color-black:#000;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-4xl:56rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-normal:400;--font-weight-bold:700;--tracking-wide:.025em;--leading-snug:1.375;--leading-relaxed:1.625;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-term-bg:#050505;--color-term-panel:#101010;--color-term-inset:#1a1a1a;--color-term-border:#2c2c2c;--color-term-border-hi:#474747;--color-term-fg:#f2f2f2;--color-term-dim:#8f8f8f;--color-term-green:#4ade80;--color-term-amber:#fbbf24;--color-term-red:#f87171;--color-term-cyan:#22d3ee;--color-term-magenta:#e879f9;--color-term-blue:#60a5fa;--color-term-purple:#a78bfa;--color-term-orange:#fb923c;--color-term-teal:#2dd4bf;--color-term-lime:#a3e635}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}html,body,#root{height:100%}body{background-color:var(--color-term-bg);font-family:var(--font-mono);--tw-leading:var(--leading-relaxed);font-size:13px;line-height:var(--leading-relaxed);color:var(--color-term-fg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}::selection{background:var(--color-term-fg);color:var(--color-term-bg)}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--color-term-bg)}::-webkit-scrollbar-thumb{background:var(--color-term-border)}::-webkit-scrollbar-thumb:hover{background:var(--color-term-border-hi)}input,textarea,select,button{font:inherit}select,option{background:var(--color-term-inset);color:var(--color-term-fg)}}@layer components{.kbd{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-term-border);background-color:var(--color-term-panel);padding-inline:var(--spacing);--tw-leading:calc(var(--spacing) * 4);font-size:11px;line-height:calc(var(--spacing) * 4);color:var(--color-term-dim);display:inline-block}.scanlines{pointer-events:none;z-index:60;background:repeating-linear-gradient(0deg,#0000 0 2px,#0000000b 3px,#0000 4px);position:fixed;inset:0}.md{--tw-leading:var(--leading-relaxed);max-width:none;font-size:13px;line-height:var(--leading-relaxed)}.md h1{margin-top:0;margin-bottom:calc(var(--spacing) * 4);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-term-border);padding-bottom:calc(var(--spacing) * 2);font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);color:var(--color-term-green)}.md h2{margin-top:calc(var(--spacing) * 7);margin-bottom:calc(var(--spacing) * 3);border-bottom-style:var(--tw-border-style);border-color:#2c2c2c99;border-bottom-width:1px}@supports (color:color-mix(in lab, red, red)){.md h2{border-color:color-mix(in oklab, var(--color-term-border) 60%, transparent)}}.md h2{padding-bottom:var(--spacing);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);color:var(--color-term-green)}.md h3{margin-top:calc(var(--spacing) * 5);margin-bottom:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);color:var(--color-term-cyan)}.md h4{margin-top:calc(var(--spacing) * 4);margin-bottom:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);color:var(--color-term-fg)}.md p{margin-block:calc(var(--spacing) * 3)}.md ul{margin-block:calc(var(--spacing) * 3);padding-left:calc(var(--spacing) * 4);list-style-type:none}.md ul>li{margin-block:var(--spacing);position:relative}.md ul>li:before{content:"▸";left:calc(var(--spacing) * -4);color:var(--color-term-dim);position:absolute}.md ul>li>ul{margin-block:var(--spacing)}.md ol{margin-block:calc(var(--spacing) * 3);padding-left:calc(var(--spacing) * 6);list-style-type:decimal}.md ol ::marker{color:var(--color-term-dim)}.md ol::marker{color:var(--color-term-dim)}.md ol ::-webkit-details-marker{color:var(--color-term-dim)}.md ol::-webkit-details-marker{color:var(--color-term-dim)}.md a{color:var(--color-term-cyan);text-underline-offset:2px;text-decoration-line:underline}@media (hover:hover){.md a:hover{color:var(--color-term-green)}}.md strong{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);color:var(--color-term-fg)}.md code:not(pre code){border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-term-border);background-color:var(--color-term-panel);padding-inline:var(--spacing);padding-block:calc(var(--spacing) * .5);color:var(--color-term-amber);font-size:12px}.md pre{margin-block:calc(var(--spacing) * 4);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-term-border);background-color:var(--color-term-inset);padding:calc(var(--spacing) * 3);overflow-x:auto}.md pre code{background:0 0;font-size:12px}.md blockquote{margin-block:calc(var(--spacing) * 3);border-left-style:var(--tw-border-style);border-color:#fbbf2499;border-left-width:2px}@supports (color:color-mix(in lab, red, red)){.md blockquote{border-color:color-mix(in oklab, var(--color-term-amber) 60%, transparent)}}.md blockquote{padding-left:calc(var(--spacing) * 3);color:var(--color-term-dim)}.md table{margin-block:calc(var(--spacing) * 4);border-collapse:collapse;width:100%}.md th{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-term-border);background-color:var(--color-term-panel);padding-inline:calc(var(--spacing) * 2);padding-block:var(--spacing);text-align:left;--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);color:var(--color-term-green)}.md td{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-term-border);padding-inline:calc(var(--spacing) * 2);padding-block:var(--spacing);vertical-align:top}.md hr{margin-block:calc(var(--spacing) * 6);border-color:var(--color-term-border)}.md input[type=checkbox]{margin-right:var(--spacing);accent-color:var(--color-emerald-500)}.hljs{background:0 0}.cm-host,.cm-host .cm-editor{height:100%}.cm-host .cm-editor{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-term-border);--tw-outline-style:none;background-color:#0000;outline-style:none;font-size:13px}.cm-host .cm-scroller{font-family:var(--font-mono)}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.top-0{top:0}.top-2{top:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.bottom-8{bottom:calc(var(--spacing) * 8)}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.col-span-2{grid-column:span 2/span 2}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-1{margin-right:var(--spacing)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:var(--spacing)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-6{margin-left:calc(var(--spacing) * 6)}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-64{height:calc(var(--spacing) * 64)}.h-\[calc\(100\%-25px\)\]{height:calc(100% - 25px)}.h-\[calc\(100\%-33px\)\]{height:calc(100% - 33px)}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-\[55vh\]{max-height:55vh}.min-h-0{min-height:0}.min-h-14{min-height:calc(var(--spacing) * 14)}.min-h-16{min-height:calc(var(--spacing) * 16)}.min-h-20{min-height:calc(var(--spacing) * 20)}.min-h-40{min-height:calc(var(--spacing) * 40)}.min-h-96{min-height:calc(var(--spacing) * 96)}.w-3{width:calc(var(--spacing) * 3)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-44{width:calc(var(--spacing) * 44)}.w-48{width:calc(var(--spacing) * 48)}.w-56{width:calc(var(--spacing) * 56)}.w-60{width:calc(var(--spacing) * 60)}.w-72{width:calc(var(--spacing) * 72)}.w-96{width:calc(var(--spacing) * 96)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.resize-y{resize:vertical}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[8rem_1fr\]{grid-template-columns:8rem 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-px{gap:1px}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-y-1{row-gap:var(--spacing)}.gap-y-3{row-gap:calc(var(--spacing) * 3)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-term-border\/40>:not(:last-child)){border-color:#2c2c2c66}@supports (color:color-mix(in lab, red, red)){:where(.divide-term-border\/40>:not(:last-child)){border-color:color-mix(in oklab, var(--color-term-border) 40%, transparent)}}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-term-amber\/40{border-color:#fbbf2466}@supports (color:color-mix(in lab, red, red)){.border-term-amber\/40{border-color:color-mix(in oklab, var(--color-term-amber) 40%, transparent)}}.border-term-bg\/50{border-color:#05050580}@supports (color:color-mix(in lab, red, red)){.border-term-bg\/50{border-color:color-mix(in oklab, var(--color-term-bg) 50%, transparent)}}.border-term-blue\/40{border-color:#60a5fa66}@supports (color:color-mix(in lab, red, red)){.border-term-blue\/40{border-color:color-mix(in oklab, var(--color-term-blue) 40%, transparent)}}.border-term-border{border-color:var(--color-term-border)}.border-term-border-hi{border-color:var(--color-term-border-hi)}.border-term-border\/30{border-color:#2c2c2c4d}@supports (color:color-mix(in lab, red, red)){.border-term-border\/30{border-color:color-mix(in oklab, var(--color-term-border) 30%, transparent)}}.border-term-border\/40{border-color:#2c2c2c66}@supports (color:color-mix(in lab, red, red)){.border-term-border\/40{border-color:color-mix(in oklab, var(--color-term-border) 40%, transparent)}}.border-term-border\/60{border-color:#2c2c2c99}@supports (color:color-mix(in lab, red, red)){.border-term-border\/60{border-color:color-mix(in oklab, var(--color-term-border) 60%, transparent)}}.border-term-cyan\/40{border-color:#22d3ee66}@supports (color:color-mix(in lab, red, red)){.border-term-cyan\/40{border-color:color-mix(in oklab, var(--color-term-cyan) 40%, transparent)}}.border-term-cyan\/50{border-color:#22d3ee80}@supports (color:color-mix(in lab, red, red)){.border-term-cyan\/50{border-color:color-mix(in oklab, var(--color-term-cyan) 50%, transparent)}}.border-term-cyan\/60{border-color:#22d3ee99}@supports (color:color-mix(in lab, red, red)){.border-term-cyan\/60{border-color:color-mix(in oklab, var(--color-term-cyan) 60%, transparent)}}.border-term-green\/40{border-color:#4ade8066}@supports (color:color-mix(in lab, red, red)){.border-term-green\/40{border-color:color-mix(in oklab, var(--color-term-green) 40%, transparent)}}.border-term-green\/60{border-color:#4ade8099}@supports (color:color-mix(in lab, red, red)){.border-term-green\/60{border-color:color-mix(in oklab, var(--color-term-green) 60%, transparent)}}.border-term-lime\/40{border-color:#a3e63566}@supports (color:color-mix(in lab, red, red)){.border-term-lime\/40{border-color:color-mix(in oklab, var(--color-term-lime) 40%, transparent)}}.border-term-magenta\/40{border-color:#e879f966}@supports (color:color-mix(in lab, red, red)){.border-term-magenta\/40{border-color:color-mix(in oklab, var(--color-term-magenta) 40%, transparent)}}.border-term-orange\/40{border-color:#fb923c66}@supports (color:color-mix(in lab, red, red)){.border-term-orange\/40{border-color:color-mix(in oklab, var(--color-term-orange) 40%, transparent)}}.border-term-purple\/40{border-color:#a78bfa66}@supports (color:color-mix(in lab, red, red)){.border-term-purple\/40{border-color:color-mix(in oklab, var(--color-term-purple) 40%, transparent)}}.border-term-red\/40{border-color:#f8717166}@supports (color:color-mix(in lab, red, red)){.border-term-red\/40{border-color:color-mix(in oklab, var(--color-term-red) 40%, transparent)}}.border-term-red\/50{border-color:#f8717180}@supports (color:color-mix(in lab, red, red)){.border-term-red\/50{border-color:color-mix(in oklab, var(--color-term-red) 50%, transparent)}}.border-term-red\/60{border-color:#f8717199}@supports (color:color-mix(in lab, red, red)){.border-term-red\/60{border-color:color-mix(in oklab, var(--color-term-red) 60%, transparent)}}.border-term-teal\/40{border-color:#2dd4bf66}@supports (color:color-mix(in lab, red, red)){.border-term-teal\/40{border-color:color-mix(in oklab, var(--color-term-teal) 40%, transparent)}}.border-transparent{border-color:#0000}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-term-bg{background-color:var(--color-term-bg)}.bg-term-bg\/70{background-color:#050505b3}@supports (color:color-mix(in lab, red, red)){.bg-term-bg\/70{background-color:color-mix(in oklab, var(--color-term-bg) 70%, transparent)}}.bg-term-cyan\/20{background-color:#22d3ee33}@supports (color:color-mix(in lab, red, red)){.bg-term-cyan\/20{background-color:color-mix(in oklab, var(--color-term-cyan) 20%, transparent)}}.bg-term-green{background-color:var(--color-term-green)}.bg-term-green\/60{background-color:#4ade8099}@supports (color:color-mix(in lab, red, red)){.bg-term-green\/60{background-color:color-mix(in oklab, var(--color-term-green) 60%, transparent)}}.bg-term-inset{background-color:var(--color-term-inset)}.bg-term-panel{background-color:var(--color-term-panel)}.p-0{padding:0}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.pt-1{padding-top:var(--spacing)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-\[12vh\]{padding-top:12vh}.pt-\[15vh\]{padding-top:15vh}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-1{padding-bottom:var(--spacing)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-inherit{color:inherit}.text-term-amber{color:var(--color-term-amber)}.text-term-bg{color:var(--color-term-bg)}.text-term-bg\/70{color:#050505b3}@supports (color:color-mix(in lab, red, red)){.text-term-bg\/70{color:color-mix(in oklab, var(--color-term-bg) 70%, transparent)}}.text-term-bg\/80{color:#050505cc}@supports (color:color-mix(in lab, red, red)){.text-term-bg\/80{color:color-mix(in oklab, var(--color-term-bg) 80%, transparent)}}.text-term-blue{color:var(--color-term-blue)}.text-term-border-hi{color:var(--color-term-border-hi)}.text-term-cyan{color:var(--color-term-cyan)}.text-term-dim{color:var(--color-term-dim)}.text-term-dim\/40{color:#8f8f8f66}@supports (color:color-mix(in lab, red, red)){.text-term-dim\/40{color:color-mix(in oklab, var(--color-term-dim) 40%, transparent)}}.text-term-dim\/70{color:#8f8f8fb3}@supports (color:color-mix(in lab, red, red)){.text-term-dim\/70{color:color-mix(in oklab, var(--color-term-dim) 70%, transparent)}}.text-term-dim\/80{color:#8f8f8fcc}@supports (color:color-mix(in lab, red, red)){.text-term-dim\/80{color:color-mix(in oklab, var(--color-term-dim) 80%, transparent)}}.text-term-fg{color:var(--color-term-fg)}.text-term-green{color:var(--color-term-green)}.text-term-lime{color:var(--color-term-lime)}.text-term-magenta{color:var(--color-term-magenta)}.text-term-orange{color:var(--color-term-orange)}.text-term-purple{color:var(--color-term-purple)}.text-term-red{color:var(--color-term-red)}.text-term-teal{color:var(--color-term-teal)}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.opacity-40{opacity:.4}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-100{opacity:1}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-black\/50{--tw-shadow-color:#00000080}@supports (color:color-mix(in lab, red, red)){.shadow-black\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-black\/60{--tw-shadow-color:#0009}@supports (color:color-mix(in lab, red, red)){.shadow-black\/60{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 60%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-black\/70{--tw-shadow-color:#000000b3}@supports (color:color-mix(in lab, red, red)){.shadow-black\/70{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 70%, transparent) var(--tw-shadow-alpha), transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.placeholder\:text-term-dim\/50::placeholder{color:#8f8f8f80}@supports (color:color-mix(in lab, red, red)){.placeholder\:text-term-dim\/50::placeholder{color:color-mix(in oklab, var(--color-term-dim) 50%, transparent)}}.placeholder\:text-term-dim\/60::placeholder{color:#8f8f8f99}@supports (color:color-mix(in lab, red, red)){.placeholder\:text-term-dim\/60::placeholder{color:color-mix(in oklab, var(--color-term-dim) 60%, transparent)}}@media (hover:hover){.hover\:border-term-cyan\/80:hover{border-color:#22d3eecc}@supports (color:color-mix(in lab, red, red)){.hover\:border-term-cyan\/80:hover{border-color:color-mix(in oklab, var(--color-term-cyan) 80%, transparent)}}.hover\:bg-term-border\/40:hover{background-color:#2c2c2c66}@supports (color:color-mix(in lab, red, red)){.hover\:bg-term-border\/40:hover{background-color:color-mix(in oklab, var(--color-term-border) 40%, transparent)}}.hover\:bg-term-cyan:hover{background-color:var(--color-term-cyan)}.hover\:bg-term-fg\/5:hover{background-color:#f2f2f20d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-term-fg\/5:hover{background-color:color-mix(in oklab, var(--color-term-fg) 5%, transparent)}}.hover\:bg-term-green:hover{background-color:var(--color-term-green)}.hover\:bg-term-inset:hover{background-color:var(--color-term-inset)}.hover\:bg-term-red:hover{background-color:var(--color-term-red)}.hover\:font-bold:hover{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.hover\:text-term-bg:hover{color:var(--color-term-bg)}.hover\:text-term-cyan:hover{color:var(--color-term-cyan)}.hover\:text-term-fg:hover{color:var(--color-term-fg)}.hover\:text-term-green:hover{color:var(--color-term-green)}.hover\:text-term-red:hover{color:var(--color-term-red)}}.focus\:border-term-green\/60:focus{border-color:#4ade8099}@supports (color:color-mix(in lab, red, red)){.focus\:border-term-green\/60:focus{border-color:color-mix(in oklab, var(--color-term-green) 60%, transparent)}}.focus\:bg-term-green:focus{background-color:var(--color-term-green)}.focus\:text-term-bg:focus{color:var(--color-term-bg)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:opacity-100:focus-visible{opacity:1}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=48rem){.md\:col-span-4{grid-column:span 4/span 4}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (width>=64rem){.lg\:col-span-5{grid-column:span 5/span 5}.lg\:block{display:block}.lg\:flex{display:flex}.lg\:inline-flex{display:inline-flex}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}@media (width>=80rem){.xl\:inline{display:inline}}}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(data:font/woff2;base64,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)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2)format("woff2-variations");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2)format("woff2-variations");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}pre code.hljs{padding:1em;display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs-meta,.hljs-comment{color:#565f89}.hljs-tag,.hljs-doctag,.hljs-selector-id,.hljs-selector-class,.hljs-regexp,.hljs-template-tag,.hljs-selector-pseudo,.hljs-selector-attr,.hljs-variable.language_,.hljs-deletion{color:#f7768e}.hljs-variable,.hljs-template-variable,.hljs-number,.hljs-literal,.hljs-type,.hljs-params,.hljs-link{color:#ff9e64}.hljs-built_in,.hljs-attribute{color:#e0af68}.hljs-keyword,.hljs-title.function_,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-subst,.hljs-property{color:#7dcfff}.hljs-selector-tag{color:#73daca}.hljs-quote,.hljs-string,.hljs-symbol,.hljs-bullet,.hljs-addition{color:#9ece6a}.hljs-code,.hljs-formula,.hljs-section{color:#7aa2f7}.hljs-name,.hljs-keyword,.hljs-operator,.hljs-keyword,.hljs-char.escape_,.hljs-attr{color:#bb9af7}.hljs-punctuation{color:#c0caf5}.hljs{color:#9aa5ce;background:#1a1b26}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}
|