vibe-coding-master 0.8.3 → 0.8.5
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 +11 -3
- package/dist/backend/api/task-routes.js +6 -0
- package/dist/backend/gateway/gateway-service.js +18 -3
- package/dist/backend/server.js +8 -2
- package/dist/backend/services/artifact-service.js +14 -0
- package/dist/backend/services/claude-hook-service.js +21 -13
- package/dist/backend/services/gate-review-service.js +4 -1
- package/dist/backend/services/pm-user-question.js +62 -0
- package/dist/backend/services/translation-service.js +49 -1
- package/dist/backend/services/user-question-reply.js +10 -0
- package/dist/backend/services/workflow-control-service.js +120 -34
- package/dist/backend/templates/harness/project-manager-agent.js +9 -3
- package/dist/backend/templates/harness/vcm-ask-user-skill.js +2 -2
- package/dist/backend/templates/harness/vcm-workflow-review-skill.js +7 -1
- package/dist-frontend/assets/index-BIFZPhDN.css +32 -0
- package/dist-frontend/assets/{index-C21rIHsU.js → index-c2YwYw6n.js} +33 -33
- package/dist-frontend/index.html +2 -2
- package/package.json +4 -1
- package/scripts/harness-tools/run-long-check +90 -43
- package/dist-frontend/assets/index-Dc0_KSf4.css +0 -32
|
@@ -122,11 +122,11 @@ export function createWorkflowControlService(deps) {
|
|
|
122
122
|
const violatedRule = candidate.proposal.violatedRule?.trim();
|
|
123
123
|
if (!authorizationText && !violatedRule) {
|
|
124
124
|
throw workflowError("WORKFLOW_TRANSITION_DENIED", verdict.reason, verdict.allowedTransitions.length > 0
|
|
125
|
-
? `Allowed next dispatches: ${verdict.allowedTransitions.join(", ")}. Recheck the flow, or ask the user
|
|
125
|
+
? `Allowed next dispatches: ${verdict.allowedTransitions.join(", ")}. Recheck the flow, reuse an existing direct user instruction that explicitly authorizes this exact transition, or ask the user only when no such authorization exists.`
|
|
126
126
|
: verdict.blockedHint);
|
|
127
127
|
}
|
|
128
128
|
if (!authorizationText || violatedRule !== verdict.reason) {
|
|
129
|
-
throw workflowError("WORKFLOW_USER_AUTHORIZATION_INVALID", `User authorization must include the exact authorization text and exact violated rule: ${verdict.reason}`, "
|
|
129
|
+
throw workflowError("WORKFLOW_USER_AUTHORIZATION_INVALID", `User authorization must include the exact authorization text and exact violated rule: ${verdict.reason}`, "Copy an existing direct user instruction that explicitly authorizes this exact transition into Authorization Text. Ask the user only when no such authorization exists. Copy the rejection reason verbatim into Violated Rule.");
|
|
130
130
|
}
|
|
131
131
|
userAuthorization = createUserAuthorization(id(), current, candidate, effectiveFlow, baseHistoryHash, verdict.reason, authorizationText, now());
|
|
132
132
|
overrideAuthorizationId = userAuthorization.id;
|
|
@@ -317,7 +317,10 @@ export function createWorkflowControlService(deps) {
|
|
|
317
317
|
},
|
|
318
318
|
requestUserInput,
|
|
319
319
|
resolveUserInput,
|
|
320
|
+
completeUserQuestion,
|
|
321
|
+
runWhileNotAwaitingUser,
|
|
320
322
|
submitProgress,
|
|
323
|
+
assertDocsArtifactAllowed,
|
|
321
324
|
assertRouteAuthorized,
|
|
322
325
|
claimDispatch,
|
|
323
326
|
releaseDispatch,
|
|
@@ -325,6 +328,37 @@ export function createWorkflowControlService(deps) {
|
|
|
325
328
|
confirmDispatch,
|
|
326
329
|
recoverTask
|
|
327
330
|
};
|
|
331
|
+
async function assertDocsArtifactAllowed(input, kind, role) {
|
|
332
|
+
const state = await getState(input);
|
|
333
|
+
failOnStateWarnings(state);
|
|
334
|
+
const progress = await readProgress(deps.fs, input);
|
|
335
|
+
const active = state.activeDispatch;
|
|
336
|
+
if (progress.status !== "active" || !active || active.targetRole !== role)
|
|
337
|
+
return;
|
|
338
|
+
let expected;
|
|
339
|
+
if (progress.flow === "docs-only") {
|
|
340
|
+
expected = "docs-update-report";
|
|
341
|
+
}
|
|
342
|
+
else if (role === "architect" && (progress.flow === "code-change"
|
|
343
|
+
|| progress.flow === "architect-debug" || progress.flow === "architecture-diagnosis")) {
|
|
344
|
+
const flow = progress.flow;
|
|
345
|
+
const run = resolveFlowRun(state.flowRun, progress);
|
|
346
|
+
const hadTester = progress.history.some((entry) => entry.sequence >= run.startedAtSequence
|
|
347
|
+
&& entry.sequence < active.sequence && entry.targetRole === "tester");
|
|
348
|
+
if (!run.activeBranch && hadTester) {
|
|
349
|
+
const source = run.resumedFromBranch ?? (flow === "code-change" ? "coder" : flow);
|
|
350
|
+
const docsTarget = `${flow}/architect`;
|
|
351
|
+
const allowed = await allowedAfterTester(deps.fs, input, state, flow, source, {
|
|
352
|
+
successTarget: docsTarget
|
|
353
|
+
});
|
|
354
|
+
if (allowed.includes(docsTarget))
|
|
355
|
+
expected = "docs-sync-report";
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (expected && expected !== kind) {
|
|
359
|
+
throw workflowError("WORKFLOW_DOCS_ARTIFACT_MISMATCH", `${kind} was not written: the active ${progress.flow} dispatch #${active.sequence} requires ${path.posix.join(input.handoffDir, `${expected}.md`)}.`, `Submit --kind ${expected} through .ai/tools/vcm-artifact. The two documentation reports are not interchangeable.`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
328
362
|
async function requestUserInput(input, question) {
|
|
329
363
|
return withLock(statePath(input), async () => {
|
|
330
364
|
const state = await getState(input);
|
|
@@ -377,6 +411,37 @@ export function createWorkflowControlService(deps) {
|
|
|
377
411
|
return next;
|
|
378
412
|
});
|
|
379
413
|
}
|
|
414
|
+
async function runWhileNotAwaitingUser(input, run) {
|
|
415
|
+
return withLock(statePath(input), async () => {
|
|
416
|
+
const state = await getState(input);
|
|
417
|
+
failWhileAwaitingUser(state);
|
|
418
|
+
return run();
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
async function completeUserQuestion(input, turn) {
|
|
422
|
+
return withLock(statePath(input), async () => {
|
|
423
|
+
const state = await getState(input);
|
|
424
|
+
failOnStateWarnings(state);
|
|
425
|
+
const question = state.awaitingUser;
|
|
426
|
+
if (!question)
|
|
427
|
+
return undefined;
|
|
428
|
+
const replies = state.userQuestionReplies ?? [];
|
|
429
|
+
const existing = replies.find((reply) => reply.requestedAt === question.requestedAt);
|
|
430
|
+
if (existing)
|
|
431
|
+
return existing.sessionId === turn.sessionId ? existing : undefined;
|
|
432
|
+
if (question.requestedAt > turn.endedAt)
|
|
433
|
+
return undefined;
|
|
434
|
+
const reply = {
|
|
435
|
+
...question,
|
|
436
|
+
id: `user-question:${turn.sessionId}:${question.requestedAt}`,
|
|
437
|
+
sessionId: turn.sessionId,
|
|
438
|
+
turnStartedAt: turn.startedAt,
|
|
439
|
+
completedAt: turn.endedAt
|
|
440
|
+
};
|
|
441
|
+
await saveState(input, { ...state, userQuestionReplies: [...replies, reply], updatedAt: now() });
|
|
442
|
+
return reply;
|
|
443
|
+
});
|
|
444
|
+
}
|
|
380
445
|
async function saveState(input, state) {
|
|
381
446
|
await deps.fs.writeJsonAtomic(statePath(input), state);
|
|
382
447
|
}
|
|
@@ -667,7 +732,7 @@ async function allowedCodeChange(fs, input, state, segment, resumedFromBranch) {
|
|
|
667
732
|
const testerIndex = findLastIndex(segment, (entry) => entry.targetRole === "tester");
|
|
668
733
|
if (resumedFromBranch && coderIndex < 0) {
|
|
669
734
|
if (testerIndex < 0) {
|
|
670
|
-
return allowedPostImplementationArchitect(fs, input, state, "code-change"
|
|
735
|
+
return allowedPostImplementationArchitect(fs, input, state, "code-change");
|
|
671
736
|
}
|
|
672
737
|
return allowedAfterTester(fs, input, state, "code-change", resumedFromBranch, {
|
|
673
738
|
testerFailureFlow: "architect-debug",
|
|
@@ -676,17 +741,7 @@ async function allowedCodeChange(fs, input, state, segment, resumedFromBranch) {
|
|
|
676
741
|
});
|
|
677
742
|
}
|
|
678
743
|
if (coderIndex < 0) {
|
|
679
|
-
|
|
680
|
-
if (!evidenceIsFresh(state, "code-change", "architect", "architecture-plan.md", plan.hash)
|
|
681
|
-
|| plan.value !== "complete")
|
|
682
|
-
return ["code-change/architect"];
|
|
683
|
-
const gate = await gateState(fs, input, "architecture-plan");
|
|
684
|
-
if (freshGateDecision(state, "code-change", "architect", "architecture-plan", gate) === "request_changes") {
|
|
685
|
-
return ["code-change/architect"];
|
|
686
|
-
}
|
|
687
|
-
return gatePassedForDispatch(state, "code-change", "architect", "architecture-plan", gate)
|
|
688
|
-
? ["code-change/coder"]
|
|
689
|
-
: [];
|
|
744
|
+
return (await allowedFreshArchitecturePlan(fs, input, state)) ?? ["code-change/architect"];
|
|
690
745
|
}
|
|
691
746
|
if (testerIndex < coderIndex) {
|
|
692
747
|
const coder = await artifactState(fs, input, "coder-completion.md", "coder-completion");
|
|
@@ -697,9 +752,8 @@ async function allowedCodeChange(fs, input, state, segment, resumedFromBranch) {
|
|
|
697
752
|
return ["architect-debug/architect"];
|
|
698
753
|
return coder.value === "ready_for_review" ? ["code-change/tester"] : ["code-change/coder"];
|
|
699
754
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
return allowedPostImplementationArchitect(fs, input, state, "code-change", architectsAfterTester);
|
|
755
|
+
if (segment.some((entry, index) => index > testerIndex && entry.targetRole === "architect")) {
|
|
756
|
+
return allowedPostImplementationArchitect(fs, input, state, "code-change");
|
|
703
757
|
}
|
|
704
758
|
return allowedAfterTester(fs, input, state, "code-change", "coder", {
|
|
705
759
|
testerFailureFlow: "architect-debug",
|
|
@@ -707,13 +761,15 @@ async function allowedCodeChange(fs, input, state, segment, resumedFromBranch) {
|
|
|
707
761
|
successTarget: "code-change/architect"
|
|
708
762
|
});
|
|
709
763
|
}
|
|
710
|
-
async function
|
|
764
|
+
async function allowedFreshArchitecturePlan(fs, input, state, gateMustPostdate) {
|
|
765
|
+
const baseline = matchingEvidenceBaseline(state, "code-change", "architect");
|
|
711
766
|
const plan = await artifactState(fs, input, "architecture-plan.md", "architecture-plan");
|
|
712
|
-
if (!
|
|
713
|
-
|
|
767
|
+
if (!baseline || baseline.artifactHashes["architecture-plan.md"] === plan.hash)
|
|
768
|
+
return undefined;
|
|
769
|
+
if (plan.value !== "complete")
|
|
714
770
|
return ["code-change/architect"];
|
|
715
771
|
const gate = await gateState(fs, input, "architecture-plan");
|
|
716
|
-
if (!gate ||
|
|
772
|
+
if (!gate || (gateMustPostdate && gate.updatedAt <= gateMustPostdate))
|
|
717
773
|
return [];
|
|
718
774
|
if (freshGateDecision(state, "code-change", "architect", "architecture-plan", gate) === "request_changes") {
|
|
719
775
|
return ["code-change/architect"];
|
|
@@ -726,7 +782,7 @@ async function allowedArchitectFix(fs, input, state, segment, source, resumedFro
|
|
|
726
782
|
const architectIndex = findLastIndex(segment, (entry) => entry.targetRole === "architect");
|
|
727
783
|
const testerIndex = findLastIndex(segment, (entry) => entry.targetRole === "tester");
|
|
728
784
|
if (resumedFromBranch && architectIndex >= 0 && testerIndex < 0) {
|
|
729
|
-
return allowedPostImplementationArchitect(fs, input, state, source
|
|
785
|
+
return allowedPostImplementationArchitect(fs, input, state, source);
|
|
730
786
|
}
|
|
731
787
|
if (architectIndex < 0)
|
|
732
788
|
return [`${source}/architect`];
|
|
@@ -773,11 +829,13 @@ async function allowedArchitectFix(fs, input, state, segment, source, resumedFro
|
|
|
773
829
|
successTarget: parentFlow ? `${parentFlow}/architect` : `${source}/architect`
|
|
774
830
|
});
|
|
775
831
|
}
|
|
776
|
-
async function allowedPostImplementationArchitect(fs, input, state, flow
|
|
832
|
+
async function allowedPostImplementationArchitect(fs, input, state, flow) {
|
|
777
833
|
const docs = await artifactState(fs, input, "docs-sync-report.md", "docs-sync-report");
|
|
778
834
|
const acceptance = await artifactState(fs, input, "final-acceptance.md", "final-acceptance");
|
|
779
|
-
if (flow === "code-change"
|
|
780
|
-
|
|
835
|
+
if (flow === "code-change") {
|
|
836
|
+
const planningTransition = await allowedFreshArchitecturePlan(fs, input, state, matchingEvidenceBaseline(state, "code-change", "architect")?.confirmedAt);
|
|
837
|
+
if (planningTransition !== undefined)
|
|
838
|
+
return planningTransition;
|
|
781
839
|
}
|
|
782
840
|
if (evidenceIsFresh(state, flow, "architect", "docs-sync-report.md", docs.hash) && docs.complete) {
|
|
783
841
|
if (docs.value === "synced" || docs.value === "unchanged") {
|
|
@@ -824,13 +882,13 @@ async function allowedAfterTester(fs, input, state, currentFlow, codeSource, opt
|
|
|
824
882
|
}
|
|
825
883
|
if (test.value === "incomplete" || test.infrastructure === "repair-required")
|
|
826
884
|
return [`${currentFlow}/tester`];
|
|
827
|
-
if (test.value === "fail" && test.infrastructure !== "repair-required") {
|
|
828
|
-
return options.testerFailureFlow ? [`${options.testerFailureFlow}/architect`] : [];
|
|
829
|
-
}
|
|
830
885
|
const validation = await gateState(fs, input, "validation-adequacy");
|
|
831
886
|
if (freshGateDecision(state, currentFlow, "tester", "validation-adequacy", validation) === "request_changes") {
|
|
832
887
|
return [`${currentFlow}/tester`];
|
|
833
888
|
}
|
|
889
|
+
if (test.value === "fail" && !test.hasUserApprovedCoverageGap) {
|
|
890
|
+
return options.testerFailureFlow ? [`${options.testerFailureFlow}/architect`] : [];
|
|
891
|
+
}
|
|
834
892
|
if (!gatePassedForDispatch(state, currentFlow, "tester", "validation-adequacy", validation))
|
|
835
893
|
return [];
|
|
836
894
|
const codeDiff = await gateState(fs, input, "code-diff");
|
|
@@ -873,6 +931,10 @@ async function artifactState(fs, input, fileName, kind) {
|
|
|
873
931
|
const infrastructure = kind === "test-report"
|
|
874
932
|
? /^Status:\s*(.+?)\s*$/mi.exec(readArtifactSectionContent(content, "Test Infrastructure") ?? "")?.[1]?.trim().toLowerCase()
|
|
875
933
|
: undefined;
|
|
934
|
+
const hasUserApprovedCoverageGap = kind === "test-report"
|
|
935
|
+
&& check.status === "ok"
|
|
936
|
+
&& hasSubstantiveArtifactSection(readArtifactSectionContent(content, "Coverage Gaps"))
|
|
937
|
+
&& hasSubstantiveArtifactSection(readArtifactSectionContent(content, "User Approval Evidence"));
|
|
876
938
|
const disposition = kind === "architect-debug" || kind === "architecture-diagnosis"
|
|
877
939
|
? readArtifactSectionContent(content, "Final Disposition")?.trim().toLowerCase()
|
|
878
940
|
: undefined;
|
|
@@ -884,12 +946,17 @@ async function artifactState(fs, input, fileName, kind) {
|
|
|
884
946
|
hash: await artifactFingerprint(fs, absolute, content),
|
|
885
947
|
value,
|
|
886
948
|
infrastructure,
|
|
949
|
+
hasUserApprovedCoverageGap,
|
|
887
950
|
disposition,
|
|
888
951
|
correctionOwner: correctionOwner === "none" || asTargetRole(correctionOwner)
|
|
889
952
|
? correctionOwner
|
|
890
953
|
: undefined
|
|
891
954
|
};
|
|
892
955
|
}
|
|
956
|
+
function hasSubstantiveArtifactSection(value) {
|
|
957
|
+
const normalized = value?.trim();
|
|
958
|
+
return Boolean(normalized && !/^(none|tbd)\.?$/i.test(normalized));
|
|
959
|
+
}
|
|
893
960
|
async function gateState(fs, input, gate) {
|
|
894
961
|
const target = resolveRepoPath(input.taskRepoRoot, path.posix.join(".ai/vcm/gate-reviews", "index.json"));
|
|
895
962
|
if (!(await fs.pathExists(target)))
|
|
@@ -1138,11 +1205,17 @@ async function validateCompleteDeliveryEvidence(fs, input, state, flow) {
|
|
|
1138
1205
|
throw workflowError("WORKFLOW_COMPLETION_INVALID", `The latest ${flow} dispatch is to ${baseline.targetRole}. Complete every required downstream validation and Gate step, then route Architect for docs sync before completing the flow.`);
|
|
1139
1206
|
}
|
|
1140
1207
|
const docs = await artifactState(fs, input, "docs-sync-report.md", "docs-sync-report");
|
|
1141
|
-
if (!docs.complete) {
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1208
|
+
if (!docs.complete || baseline.artifactHashes["docs-sync-report.md"] === docs.hash) {
|
|
1209
|
+
const update = await artifactState(fs, input, "docs-update-report.md", "docs-update-report");
|
|
1210
|
+
const wrongReport = update.hash !== MISSING_EVIDENCE_HASH
|
|
1211
|
+
&& baseline.artifactHashes["docs-update-report.md"] !== update.hash;
|
|
1212
|
+
const reason = !docs.complete
|
|
1213
|
+
? "Docs Sync Report is missing or malformed for this complete delivery flow."
|
|
1214
|
+
: "Docs Sync Report was not produced after the final Architect dispatch.";
|
|
1215
|
+
throw workflowError("WORKFLOW_COMPLETION_INVALID", `${reason} Required file: ${path.posix.join(input.handoffDir, "docs-sync-report.md")}, produced after dispatch #${baseline.sequence} (${baseline.confirmedAt}).`
|
|
1216
|
+
+ (wrongReport
|
|
1217
|
+
? ` ${path.posix.join(input.handoffDir, "docs-update-report.md")} was updated after this dispatch, but cannot replace docs-sync-report.md.`
|
|
1218
|
+
: ""), "Ask Architect to submit --kind docs-sync-report through .ai/tools/vcm-artifact with Decision: synced or unchanged and Correction Owner: none. Report blocked with its correction owner when synchronization is incomplete.");
|
|
1146
1219
|
}
|
|
1147
1220
|
if (docs.value !== "synced" && docs.value !== "unchanged") {
|
|
1148
1221
|
throw workflowError("WORKFLOW_COMPLETION_INVALID", `Docs Sync Report Decision must be synced or unchanged before completion; found ${docs.value ?? "missing"}.`);
|
|
@@ -1303,18 +1376,24 @@ function normalizeState(value, taskSlug, timestamp) {
|
|
|
1303
1376
|
const awaitingUser = value.awaitingUser === undefined || value.awaitingUser === null
|
|
1304
1377
|
? null
|
|
1305
1378
|
: isAwaitingUser(value.awaitingUser) ? value.awaitingUser : undefined;
|
|
1379
|
+
const validQuestionReplies = value.userQuestionReplies === undefined
|
|
1380
|
+
|| (Array.isArray(value.userQuestionReplies) && value.userQuestionReplies.every(isUserQuestionReply));
|
|
1306
1381
|
if (pendingDispatch === undefined
|
|
1307
1382
|
|| activeDispatch === undefined
|
|
1308
1383
|
|| flowRun === undefined
|
|
1309
1384
|
|| userAuthorizations === undefined
|
|
1310
1385
|
|| userApprovedFollowUps === undefined
|
|
1311
|
-
|| awaitingUser === undefined
|
|
1386
|
+
|| awaitingUser === undefined
|
|
1387
|
+
|| !validQuestionReplies) {
|
|
1312
1388
|
return { ...emptyState(taskSlug, timestamp), warnings: ["Workflow control state has an unsupported shape."] };
|
|
1313
1389
|
}
|
|
1314
1390
|
return {
|
|
1315
1391
|
version: 1,
|
|
1316
1392
|
taskSlug,
|
|
1317
1393
|
awaitingUser,
|
|
1394
|
+
...(Array.isArray(value.userQuestionReplies) ? {
|
|
1395
|
+
userQuestionReplies: value.userQuestionReplies
|
|
1396
|
+
} : {}),
|
|
1318
1397
|
pendingDispatch,
|
|
1319
1398
|
activeDispatch,
|
|
1320
1399
|
flowRun,
|
|
@@ -1324,6 +1403,13 @@ function normalizeState(value, taskSlug, timestamp) {
|
|
|
1324
1403
|
updatedAt: typeof value.updatedAt === "string" ? value.updatedAt : timestamp
|
|
1325
1404
|
};
|
|
1326
1405
|
}
|
|
1406
|
+
function isUserQuestionReply(value) {
|
|
1407
|
+
if (!value || typeof value !== "object")
|
|
1408
|
+
return false;
|
|
1409
|
+
const reply = value;
|
|
1410
|
+
return [reply.id, reply.sessionId, reply.question, reply.requestedAt, reply.turnStartedAt, reply.completedAt]
|
|
1411
|
+
.every((field) => typeof field === "string" && field.length > 0);
|
|
1412
|
+
}
|
|
1327
1413
|
function emptyState(taskSlug, timestamp) {
|
|
1328
1414
|
return {
|
|
1329
1415
|
version: 1,
|
|
@@ -18,6 +18,10 @@ ${renderRoleMemoryRules("project-manager")}
|
|
|
18
18
|
|
|
19
19
|
### User Communication
|
|
20
20
|
|
|
21
|
+
- Assistant text emitted before a tool call or role dispatch while the current Round continues is not user communication. Do not use intermediate text to deliver status, findings, decisions, questions, or required actions to the user.
|
|
22
|
+
- The user is informed only by PM's Round Final Reply when the Round pauses for user input or reaches a terminal result.
|
|
23
|
+
- The Round Final Reply must be self-contained. Restate every result, blocker, decision, risk, and required user action needed to understand the current state. Never rely on earlier PM text in the same Round.
|
|
24
|
+
- When asking the user a question, submit the complete user-facing question and its necessary context through \`vcm-ask-user\`, then end the turn. VCM delivers the registered question as the Round Final Reply; do not rely on a separate final message to supply missing context.
|
|
21
25
|
- Explain task status, blockers, role results, and decisions in user-facing language.
|
|
22
26
|
- Prefer plain logic over code-level detail: describe what changed, why it matters, what risk remains, and what decision is needed.
|
|
23
27
|
- Exclude irrelevant implementation detail, but retain the technical facts needed to explain the cause, evidence, impact, and unresolved state. Plain language means translating technical detail, not deleting it.
|
|
@@ -77,7 +81,7 @@ PM owns task flow selection. Every user request that asks VCM to perform deliver
|
|
|
77
81
|
|
|
78
82
|
- After PM selects a flow, only its defined main path and explicitly allowed branches may be used.
|
|
79
83
|
- The active flow may change only through a transition explicitly defined by that flow or an explicit user instruction.
|
|
80
|
-
- Only the user may authorize any other flow change.
|
|
84
|
+
- Only the user may authorize any other flow change. A direct user instruction that explicitly authorizes the exact change is the authorization. Reuse that instruction verbatim and do not ask the user to confirm it again.
|
|
81
85
|
- A role request, role result, tool suggestion, requested next action, workload, task size, context size, difficulty, predicted risk, or PM discretion must not create an unlisted branch or change the active flow.
|
|
82
86
|
- If a role requests an unlisted branch or role handoff, keep the current flow active and return the incomplete work to the current responsible role.
|
|
83
87
|
- An incomplete, unrecognized, or non-standard role result returns to the same role for a valid result.
|
|
@@ -90,6 +94,8 @@ The main flow is:
|
|
|
90
94
|
|
|
91
95
|
\`Architect Interview and planning -> architecture-plan Gate -> Coder implementation -> Tester validation -> validation-adequacy Gate -> code-diff Gate -> Architect docs sync -> Final Acceptance -> completed\`
|
|
92
96
|
|
|
97
|
+
Require \`.ai/vcm/handoffs/docs-sync-report.md\` from the current Architect docs-sync dispatch. \`docs-update-report.md\` cannot replace it.
|
|
98
|
+
|
|
93
99
|
PM may leave this path only through the allowed branches below.
|
|
94
100
|
|
|
95
101
|
#### Allowed Branches
|
|
@@ -171,7 +177,7 @@ The shared path is:
|
|
|
171
177
|
|
|
172
178
|
#### Successful Exit
|
|
173
179
|
|
|
174
|
-
- For Architect Debug Flow, code-diff approval continues to \`Architect docs sync -> Final Acceptance\`.
|
|
180
|
+
- For Architect Debug Flow, code-diff approval continues to \`Architect docs sync -> Final Acceptance\`. Require \`.ai/vcm/handoffs/docs-sync-report.md\` from this docs-sync dispatch with \`Decision: synced\` or \`unchanged\` and \`Correction Owner: none\`; handle \`blocked\` through Docs Sync Correction.
|
|
175
181
|
- For Architect Debug Branch, code-diff approval returns to the recorded parent-flow resume point after the parent flow's validation and code-diff milestones. The branch does not run its own docs sync or Final Acceptance.
|
|
176
182
|
|
|
177
183
|
Architect Debug Flow or Branch never routes implementation to Coder. Architect executes Architect Debug Mode; PM owns whether the current context is a Flow or Branch and where it continues afterward.
|
|
@@ -207,7 +213,7 @@ Architecture Diagnosis Mode must run before another Debug Mode fix or Coder disp
|
|
|
207
213
|
|
|
208
214
|
- An analysis-only Architecture Diagnosis Flow completes from the diagnosis result.
|
|
209
215
|
- An analysis-only Architecture Diagnosis Branch returns to the recorded parent-flow resume point.
|
|
210
|
-
- A code-producing Architecture Diagnosis Flow continues after code-diff approval to \`Architect docs sync -> Final Acceptance\`.
|
|
216
|
+
- A code-producing Architecture Diagnosis Flow continues after code-diff approval to \`Architect docs sync -> Final Acceptance\`. Require \`.ai/vcm/handoffs/docs-sync-report.md\` from this docs-sync dispatch with \`Decision: synced\` or \`unchanged\` and \`Correction Owner: none\`; handle \`blocked\` through Docs Sync Correction.
|
|
211
217
|
- A code-producing Architecture Diagnosis Branch returns after code-diff approval to the recorded parent-flow resume point after the parent flow's validation and code-diff milestones. It does not run its own docs sync or Final Acceptance.
|
|
212
218
|
|
|
213
219
|
After Tester Failure, PM should summarize:
|
|
@@ -5,13 +5,13 @@ Use this skill whenever Project Manager asks the user a question.
|
|
|
5
5
|
|
|
6
6
|
## Ask And Wait
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Submit the complete user-facing question, including the context needed to answer:
|
|
9
9
|
|
|
10
10
|
\`\`\`bash
|
|
11
11
|
.ai/tools/vcm-ask-user --question "<exact question>"
|
|
12
12
|
\`\`\`
|
|
13
13
|
|
|
14
|
-
After the tool returns \`awaiting_user\`,
|
|
14
|
+
After the tool returns \`awaiting_user\`, end the turn. VCM delivers the registered question as the Round Final Reply through the existing display, translation, and Gateway paths. Do not rely on a separate final message to supply missing context. Do not request Workflow Review, write a route message, run a Gate, or advance the workflow in the same turn.
|
|
15
15
|
|
|
16
16
|
Every question pauses the workflow. PM may defer a question by not asking it; once PM asks, only a new direct user message resumes the workflow. The previous workflow approval is canceled, so request a fresh approval before the next dispatch.
|
|
17
17
|
`;
|
|
@@ -48,7 +48,13 @@ If VCM rejects the transition, remain in the current PM turn and choose a legal
|
|
|
48
48
|
|
|
49
49
|
## User Authorization
|
|
50
50
|
|
|
51
|
-
Only the user's explicit instruction may authorize a rejected transition.
|
|
51
|
+
Only the user's explicit instruction may authorize a rejected transition.
|
|
52
|
+
|
|
53
|
+
If the current user instruction already explicitly authorizes the exact rejected transition, reuse that instruction verbatim as \`Authorization Text\`. Do not ask the user to confirm it again.
|
|
54
|
+
|
|
55
|
+
If no such instruction exists, use \`vcm-ask-user\` with the complete authorization question and end the turn.
|
|
56
|
+
|
|
57
|
+
Resubmit the unchanged transition with:
|
|
52
58
|
|
|
53
59
|
\`\`\`text
|
|
54
60
|
Authorization Text: <user's exact authorization>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
|
3
|
+
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
|
4
|
+
* https://github.com/chjj/term.js
|
|
5
|
+
* @license MIT
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice shall be included in
|
|
15
|
+
* all copies or substantial portions of the Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
* THE SOFTWARE.
|
|
24
|
+
*
|
|
25
|
+
* Originally forked from (with the author's permission):
|
|
26
|
+
* Fabrice Bellard's javascript vt100 for jslinux:
|
|
27
|
+
* http://bellard.org/jslinux/
|
|
28
|
+
* Copyright (c) 2011 Fabrice Bellard
|
|
29
|
+
* The original design remains. The terminal itself
|
|
30
|
+
* has been extended to include xterm CSI codes, among
|
|
31
|
+
* other features.
|
|
32
|
+
*/.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}:root{color-scheme:light;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;background:#f5f2ea;color:#1c2024;line-height:1.5}html,body,#root{height:100%}*{box-sizing:border-box}body{margin:0;min-width:320px;min-height:100vh;background:#f5f2ea}button,input,select,textarea{font:inherit}button{border:1px solid #9ba6ad;background:#f8f7f2;color:#1d252b;border-radius:6px;min-height:34px;padding:6px 10px;cursor:pointer}button:hover:not(:disabled){background:#eef4f2;border-color:#607d74}button:disabled{cursor:not-allowed;opacity:.55}.danger-button{border-color:#b84a45;background:#fff1ee;color:#8d211d;font-weight:750}.danger-button:hover:not(:disabled){border-color:#8d211d;background:#ffe2dc}input,select,textarea:not(.xterm-helper-textarea){width:100%;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326;padding:8px 10px}textarea:not(.xterm-helper-textarea){min-height:240px;resize:vertical;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px}h1,h2,p{margin-top:0}h1{margin-bottom:4px;font-size:26px;line-height:1.15}h2{margin-bottom:10px;font-size:14px;letter-spacing:0}.app-shell{display:grid;grid-template-columns:minmax(280px,320px) minmax(0,1fr);height:100vh;min-height:0;overflow:hidden}.app-shell.is-sidebar-collapsed{grid-template-columns:46px minmax(0,1fr)}.app-sidebar{position:relative;display:flex;flex-direction:column;min-width:0;border-right:1px solid #d3c9b8;background:#fbfaf6;padding:14px;overflow:auto}.app-shell.is-sidebar-collapsed .app-sidebar{overflow:hidden;padding:8px}.sidebar-toggle{position:absolute;top:10px;right:10px;z-index:2;display:grid;place-items:center;width:28px;min-height:28px;padding:0;background:#fffdf8}.sidebar-toggle:before{width:8px;height:8px;border-color:currentColor;border-style:solid;border-width:0 2px 2px 0;content:"";transform:translate(2px) rotate(135deg)}.app-shell.is-sidebar-collapsed .sidebar-toggle{left:9px;right:auto}.app-shell.is-sidebar-collapsed .sidebar-toggle:before{transform:translate(-2px) rotate(-45deg)}.sidebar-content{display:flex;flex:1;min-width:0;min-height:0}.project-dashboard{display:flex;flex:1;flex-direction:column;width:100%;min-height:100%}.app-shell.is-sidebar-collapsed .sidebar-content{width:0;opacity:0;pointer-events:none}.app-main{min-width:0;height:100%;padding:14px 16px;overflow:auto}.brand-header{display:flex;gap:12px;align-items:baseline;margin-bottom:10px;padding-right:34px}.brand-header strong{font-size:18px}.brand-header span,.muted{color:#667071;font-size:13px}.sidebar-section{margin-bottom:8px;border:1px solid #e0d6c7;border-radius:8px;background:#fffdfa;overflow:hidden}.sidebar-section-toggle{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;width:100%;min-height:34px;border:0;border-radius:0;background:transparent;color:#1c2024;font-size:13px;font-weight:750;text-align:left}.sidebar-section-toggle:hover{background:#f5f1e8}.sidebar-section-toggle[aria-expanded=true]{border-bottom:1px solid #ece5d9}.sidebar-section-chevron{width:8px;height:8px;border-color:currentColor;border-style:solid;border-width:0 2px 2px 0;transform:rotate(45deg)}.sidebar-section-toggle[aria-expanded=true] .sidebar-section-chevron{transform:rotate(-135deg)}.sidebar-section-content{padding:8px}.repo-connect,.project-summary,.repository-panel,.gateway-panel,.harness-panel,.task-create{margin:0}.repository-panel{display:grid;gap:10px}.repository-panel .project-summary{padding-top:10px;border-top:1px solid #ece5d9}.inline-form{display:grid;grid-template-columns:minmax(0,1fr);gap:8px}.inline-form.has-recent-paths{grid-template-columns:minmax(0,1fr) auto}.inline-form>input{grid-column:1 / -1}.inline-form>button{justify-self:end}.inline-form.has-recent-paths>button{justify-self:auto}.repo-recent-select{min-width:0;max-width:none}.project-summary dl{display:grid;gap:8px;margin:0}.project-summary div{min-width:0}.project-summary dt{color:#6c6255;font-size:12px}.project-summary dd{margin:0;overflow-wrap:anywhere;font-size:13px}.connected-repo-actions{display:flex;align-items:center;gap:8px;margin-top:10px}.connected-repo-actions button{min-height:30px}.gateway-actions{display:grid;gap:8px;margin-top:10px}.gateway-actions button{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;width:100%;text-align:left}.gateway-actions .settings-toggle.is-active{border-color:#2f6f73;background:#e8f1ef}.gateway-panel .compact-field,.gateway-lark-settings{display:grid;gap:6px}.gateway-panel .compact-field{font-size:12px;color:#6c6255}.gateway-panel .compact-field input,.gateway-panel .compact-field select{width:100%;min-width:0}.gateway-lark-settings{margin-top:10px}.gateway-lark-settings button{width:100%}.gateway-qr{display:grid;gap:6px;margin-top:10px}.gateway-qr img{width:100%;max-width:180px;border:1px solid #d3c9b8;border-radius:6px;background:#fff;padding:6px}.gateway-qr code{overflow-wrap:anywhere;font-size:11px}.warnings{border:1px solid #c87b54;background:#fff4ed;color:#6f3218;border-radius:6px;padding:10px 12px}.success-banner{border:1px solid #2ea043;background:#eefbf0;color:#165c26;border-radius:6px;padding:10px 12px}.flow-pause-alert-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:100;display:grid;place-items:center;background:#1f242b85;padding:20px}.flow-pause-alert{display:grid;gap:12px;width:min(460px,100%);max-height:calc(100dvh - 40px);overflow-y:auto;border:1px solid #2f6f73;border-radius:8px;background:#e8f4f2;color:#123f43;box-shadow:0 28px 72px #1f242b47;padding:22px}.flow-pause-alert-kicker{margin:0;color:#2f6f73;font-size:12px;font-weight:700;text-transform:uppercase}.flow-pause-alert h2{margin:0;font-size:24px;line-height:1.15}.flow-pause-alert p{margin:0;font-size:14px;line-height:1.5;overflow-wrap:anywhere}#flow-pause-alert-body{white-space:pre-wrap}.flow-pause-alert-hint{color:#49666a}.flow-pause-alert button{justify-self:end;min-width:110px;border:1px solid #2f6f73;background:#2f6f73;color:#fffdf8}.flow-pause-alert button:hover{background:#245c60}.ui-error-center{position:fixed;top:14px;right:14px;z-index:95;display:grid;gap:8px;width:min(520px,calc(100vw - 28px));max-height:min(58vh,540px);border:1px solid #c87b54;border-radius:8px;background:#fff4ed;color:#6f3218;box-shadow:0 18px 50px #1f242b33;padding:10px}.ui-error-center-header{display:flex;align-items:center;justify-content:space-between;gap:10px}.ui-error-center-header h2{margin:0;font-size:14px;line-height:1.2}.ui-error-center-header p{margin:2px 0 0;color:#8b4a28;font-size:11px;font-weight:700}.ui-error-center button{border-color:#c87b54;color:#6f3218;min-height:28px;padding:4px 8px;font-size:12px}.ui-error-list{display:grid;gap:8px;margin:0;padding:0;overflow:auto;list-style:none}.ui-error-list li{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:start;border-top:1px solid rgba(200,123,84,.32);padding-top:8px}.ui-error-list p{margin:0;font-size:12px;font-weight:700;line-height:1.4;overflow-wrap:anywhere}.ui-error-list span{display:block;margin-top:4px;color:#8b4a28;font-size:11px;font-weight:700}.role-recovery-toast{position:fixed;left:50%;bottom:18px;z-index:90;display:flex;align-items:center;gap:12px;max-width:calc(100vw - 32px);border:1px solid #b7791f;border-radius:8px;background:#fff8e6;color:#5f3b00;box-shadow:0 14px 42px #1f242b2e;padding:10px 12px;transform:translate(-50%)}.role-recovery-toast span{font-size:13px;font-weight:700;white-space:nowrap}.role-recovery-toast button{border-color:#b7791f;color:#5f3b00}.warnings{margin:12px 0 0;padding-left:26px;font-size:13px}.harness-panel{display:grid;gap:10px}.harness-stage{display:grid;gap:8px}.harness-panel-header{display:flex;justify-content:space-between;gap:8px;align-items:center}.harness-panel-header h2,.harness-panel-header p,.harness-result p{margin-bottom:0}.harness-actions{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.harness-review-diff-button{width:100%}.harness-file-list-title{margin:0;font-size:12px}.harness-file-list{display:grid;gap:6px;margin:0;padding:0;list-style:none}.harness-file-list li{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;border:1px solid #ece5d9;border-radius:6px;padding:6px 8px;background:#fffdfa}.harness-file-list span{overflow:hidden;font-size:12px;font-weight:650;text-overflow:ellipsis;white-space:nowrap}.harness-changes,.harness-result{border:1px solid #e0d6c7;border-radius:6px;padding:8px;background:#f8f7f2;font-size:12px}.harness-changes h3{margin:0 0 4px;font-size:12px}.harness-changes ul,.harness-result ul{margin:0;padding-left:18px}.harness-bootstrap-modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:80;display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr);background:#1f242b94;padding:14px}.harness-bootstrap-modal-surface{min-width:0;min-height:0;display:grid;grid-template-rows:auto auto minmax(0,1fr);gap:10px;border:1px solid #b9b0a1;border-radius:8px;background:#fffdf8;box-shadow:0 22px 64px #1f242b47;padding:10px}.harness-bootstrap-modal-header{display:flex;gap:12px;align-items:center;justify-content:space-between;min-width:0}.harness-bootstrap-modal-header p{max-width:min(720px,70vw);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.harness-bootstrap-modal-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:flex-end}.harness-bootstrap-controls{display:grid;grid-template-columns:minmax(180px,.8fr) minmax(180px,.9fr) minmax(140px,.7fr) auto;gap:8px;align-items:end;min-width:0}.harness-bootstrap-controls label{display:grid;gap:4px;min-width:0}.harness-bootstrap-controls label span{color:#5f6a6c;font-size:11px;font-weight:650}.harness-bootstrap-controls select{width:100%;min-width:0;min-height:30px;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326;padding:3px 8px;font-size:12px}.harness-bootstrap-control-actions{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.harness-bootstrap-control-actions button{min-height:30px;padding:4px 9px;font-size:12px}.harness-bootstrap-terminal{min-width:0;min-height:0;display:grid}.task-create form{display:grid;gap:8px}.task-panel{display:grid;gap:10px}.task-panel-actions{display:grid;gap:8px;padding-top:10px;border-top:1px solid #ece5d9}.task-panel-actions .danger-button{width:100%;text-align:center}.task-create-preview{display:grid;gap:2px;border:1px solid #e0d6c7;border-radius:6px;background:#f8f7f2;padding:6px 8px}.task-create-option{display:flex;align-items:center;gap:8px;color:#1f242b;font-size:13px;font-weight:700}.task-create-option input{width:16px;height:16px;margin:0}.task-create-preview span{color:#255f3d;font-size:12px;font-weight:700}.task-create-preview small{overflow:hidden;color:#687273;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.task-nav{display:grid;gap:8px}.task-nav-item{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;text-align:left}.task-nav-item.is-active,.role-tab.is-active{border-color:#2f6f73;background:#e8f1ef}.sidebar-settings{display:grid;gap:8px}.gate-review-setting{display:grid;gap:6px}.sidebar-settings button{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;width:100%;text-align:left}.sidebar-settings .settings-toggle.is-active{border-color:#2f6f73;background:#e8f1ef}.switch-control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:center;min-height:34px;border:1px solid #b9c0c4;border-radius:7px;background:#fffefa;color:#3f474a;padding:5px 8px;text-align:left}.switch-control:hover:not(:disabled){border-color:#2f7e84;background:#f2faf8}.switch-control:disabled{opacity:.6;cursor:not-allowed}.switch-control-label{min-width:0;overflow:hidden;font-weight:700;text-overflow:ellipsis;white-space:nowrap}.switch-control-track{position:relative;justify-self:end;width:38px;height:20px;border-radius:999px;background:#b9c0c4;transition:background .16s ease}.switch-control-thumb{position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:999px;background:#fffefa;box-shadow:0 1px 3px #12161838;transition:transform .16s ease}.switch-control.is-on{border-color:#2f7e84;background:#e8f4f2;color:#145e64}.switch-control.is-on .switch-control-track{background:#2f7e84}.switch-control.is-on .switch-control-thumb{transform:translate(18px)}.sidebar-settings .switch-control,.gateway-actions .switch-control{width:100%}.sidebar-settings .theme-mode-toggle span:last-child{font-weight:750}.settings-select-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;width:100%;font-size:13px;color:#5f6a6c}.settings-select-row select{min-height:30px;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326}.codex-bridge-settings{display:grid;gap:8px;border-top:1px solid #d4cec3;padding-top:8px}.codex-bridge-api-key-form{display:grid;gap:5px;color:#5f6a6c;font-size:13px}.codex-bridge-api-key-form>div,.codex-bridge-actions{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px}.codex-bridge-api-key-form input{min-width:0;min-height:30px;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326;padding:4px 7px}.codex-bridge-actions button{display:block;text-align:center}.settings-status-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;min-height:30px;border:1px solid #d4cec3;border-radius:6px;background:#fffdf8;padding:6px 10px;color:#5f6a6c;font-size:13px}.settings-status-row strong{color:#202326;font-size:12px}.settings-help-text{margin:0;color:#7b5e00;font-size:12px;line-height:1.35}.task-status-dock{display:grid;gap:10px;margin-top:auto;border-top:1px solid #d3c9b8;padding-top:10px}.task-status-dock-title,.current-round-title{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center}.task-status-dock-title strong{overflow:hidden;font-size:13px;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.task-status-stats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;margin:0}.task-status-stats div,.current-round-status{min-width:0;border:1px solid #e0d6c7;border-radius:6px;background:#fffdfa}.task-status-stats div{padding:6px 7px}.task-status-stats dt{color:#6c6255;font-size:10px;font-weight:700;text-transform:uppercase}.task-status-stats dd{margin:0;overflow:hidden;color:#1f242b;font-size:12px;font-weight:750;text-overflow:ellipsis;white-space:nowrap}.current-round-status{display:grid;gap:8px;padding:8px}.current-round-title span:first-child{color:#3a4647;font-size:12px;font-weight:750}.workspace-header{display:grid;grid-template-columns:minmax(120px,max-content) minmax(0,1fr);gap:10px;align-items:center;margin-bottom:6px}.workspace-title-line{display:grid;gap:2px;max-width:260px;min-width:0}.workspace-title-line h1{margin-bottom:0;overflow:hidden;font-size:18px;line-height:1.15;text-overflow:ellipsis;white-space:nowrap}.workspace-workflow-state{display:flex;gap:5px;min-width:0;color:#66717c;font-size:10px;line-height:1.2}.workspace-workflow-state span,.workspace-workflow-state strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.workspace-workflow-state strong{color:#34434b;font-weight:700}.workspace-workflow-state strong:before{content:"/";margin-right:5px;color:#8b959d}.role-tabs{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:6px;margin-bottom:8px;min-width:0}.workspace-header .role-tabs{margin-bottom:0}.role-tab{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:center;min-height:30px;padding:4px 8px;text-align:left}.workspace-grid{display:grid;grid-template-columns:minmax(0,1fr);flex:1;gap:10px;align-items:stretch;min-height:0}.workspace-main{min-width:0;min-height:0;display:flex;flex-direction:column;gap:8px}.role-console-stack{min-width:0;min-height:0;flex:1;display:flex;flex-direction:column}.role-console-panel{min-width:0;min-height:0;flex:1;display:none}.role-console-panel.is-active{display:flex;flex-direction:column}.session-console,.message-panel,.event-log,.empty-workspace{border:1px solid #d6d0c6;border-radius:8px;background:#fffdf8;padding:10px}.task-workspace{display:flex;flex-direction:column;gap:8px;height:100%;min-height:0}.workspace-runtime-warning{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;align-items:center;border:1px solid #c87b54;border-radius:6px;background:#fff4ed;color:#6f3218;padding:8px 12px;font-size:13px}.workspace-runtime-warning span{min-width:0;overflow-wrap:anywhere}.workspace-runtime-warning code{font-size:11px}.session-console{display:flex;flex-direction:column;flex:1;height:100%;min-height:0}.session-controls{display:flex;flex-wrap:nowrap;gap:6px;align-items:center;justify-content:flex-start;min-width:0;margin:0;overflow:hidden}.session-option-field{display:grid;grid-template-columns:auto minmax(120px,1fr);flex:0 1 210px;gap:5px;align-items:center;min-width:0}.permission-mode-field{flex-basis:250px}.model-field{flex-basis:220px}.effort-field{grid-template-columns:auto minmax(92px,1fr);flex-basis:150px}.session-option-field span{color:#5f6a6c;font-size:11px;font-weight:650;line-height:1;white-space:nowrap}.session-option-field small{display:block;color:#7b8587;font-size:11px;font-weight:500;line-height:1.2}.session-option-field select{width:100%;min-width:0;min-height:26px;border:1px solid #b9b0a1;border-radius:6px;background:#fffdf8;color:#202326;padding:2px 7px;font-size:12px}.session-toolbar{display:flex;flex:0 0 auto;flex-wrap:nowrap;gap:5px;margin-left:auto;justify-content:flex-end}.session-toolbar button{min-height:26px;padding:2px 8px;font-size:12px}.session-harness-notice{display:inline-flex;flex:0 0 auto;gap:6px;align-items:center;min-width:0;border:1px solid #c4a34e;border-radius:6px;background:#fff8dd;color:#604e16;padding:2px 5px;font-size:11px}.session-harness-notice span:not(.status-badge){white-space:nowrap}.session-harness-notice button{min-height:24px;padding:1px 7px;font-size:11px}.session-console-body{display:grid;grid-template-columns:minmax(0,1fr);flex:1;min-width:0;min-height:0;height:100%}.session-console-body.has-translation{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px;align-items:stretch}.terminal-pane,.translation-pane{display:grid;min-width:0;min-height:0;height:100%}.terminal-pane{grid-template-rows:auto minmax(0,1fr);gap:8px}.translation-pane{grid-template-rows:minmax(0,1fr)}.terminal-frame-shell,.terminal-empty{width:100%;height:100%;min-height:0;border-radius:6px;overflow:hidden;background:#111316}.terminal-frame-shell{position:relative}.terminal-frame{width:100%;height:100%;min-height:0}.terminal-copy-button{position:absolute;top:8px;right:8px;z-index:5;min-height:24px;border-color:#8b949e8c;border-radius:6px;background:#161b22db;color:#c9d1d9;padding:2px 8px;font-size:11px;font-weight:650;opacity:.72}.terminal-copy-button:hover:not(:disabled),.terminal-copy-button:focus-visible{background:#21262df5;border-color:#58a6ff;color:#f0f6fc;opacity:1}.terminal-copy-button.is-copied{border-color:#2ea043;color:#b7f7c4}.terminal-copy-button.is-ready{border-color:#58a6ff;color:#c9e4ff}.terminal-copy-button.is-empty,.terminal-copy-button.is-failed{border-color:#d29922;color:#ffe8a3}.terminal-empty{display:grid;place-items:center;align-content:center;gap:8px;color:#d6d0c6;border:1px solid #292d31}.translation-panel{display:flex;flex-direction:column;gap:8px;height:100%;min-height:0;border:1px solid #292d31;border-radius:6px;background:#0d1117;color:#d6deeb;padding:8px;min-width:0;width:100%;overflow:hidden;font-family:Menlo,Monaco,Consolas,monospace}.file-translation-backdrop{background:#010409b8}.translation-file-browser-backdrop{z-index:24}.file-translation-modal{display:grid;grid-template-rows:auto auto minmax(0,1fr);gap:12px;width:95vw;height:95vh;min-height:0;min-width:0;overflow:hidden;border:1px solid #30363d;border-radius:8px;background:#0d1117;color:#d6deeb;padding:14px;box-shadow:0 28px 80px #0000008f;font-family:Menlo,Monaco,Consolas,monospace}.file-translation-header{display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between;min-width:0}.file-translation-header h2,.file-translation-header p{margin-bottom:0}.file-translation-header h2{font-size:18px}.file-translation-header p{color:#8b949e;font-size:12px}.file-translation-toolbar{display:flex;flex-wrap:wrap;gap:6px}.file-translation-toolbar button{border-color:#3a4149;background:#161b22;color:#d6deeb;min-height:26px;padding:2px 8px;font-size:12px}.file-translation-layout{display:grid;grid-template-columns:minmax(220px,300px) minmax(0,1fr);gap:10px;min-height:0;min-width:0;overflow:hidden}.file-translation-list,.file-translation-preview{min-height:0;min-width:0;overflow:auto;border:1px solid #292d31;border-radius:6px;background:#0b0f14;padding:8px}.file-translation-list{display:grid;align-content:start;gap:6px}.file-translation-item{display:grid;gap:3px;width:100%;min-width:0;border:1px solid #292d31;border-radius:6px;background:#111820;color:#d6deeb;padding:6px;text-align:left}.file-translation-item strong,.file-translation-item span{overflow-wrap:anywhere}.file-translation-item span{color:#8b949e;font-size:11px}.file-translation-item.is-active{border-color:#58a6ff;background:#142033}.file-translation-preview header{display:flex;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-bottom:8px;color:#8b949e;font-size:12px}.file-translation-preview{display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden;padding:10px}.file-translation-preview .translation-markdown{min-height:0;overflow:auto;padding-right:4px;font-size:13px;line-height:1.62}.file-translation-preview>.muted{align-self:center;justify-self:center;text-align:center}.translation-file-browser-modal{display:grid;grid-template-rows:auto auto minmax(0,1fr);gap:12px;width:min(880px,calc(100vw - 32px));max-height:min(760px,calc(100vh - 48px));min-height:520px;min-width:0;overflow:hidden;border:1px solid #30363d;border-radius:8px;background:#0d1117;color:#d6deeb;padding:14px;box-shadow:0 24px 70px #0000007a;font-family:Menlo,Monaco,Consolas,monospace}.translation-file-browser-modal header,.translation-file-browser-controls,.translation-file-browser-nav,.translation-file-browser-search{display:flex;flex-wrap:wrap;gap:8px;align-items:center;min-width:0}.translation-file-browser-modal header{justify-content:space-between}.translation-file-browser-modal h2,.translation-file-browser-modal h3,.translation-file-browser-modal p{margin-bottom:0}.translation-file-browser-modal h2{font-size:17px}.translation-file-browser-modal h3{color:#8b949e;font-size:12px;font-weight:600}.translation-file-browser-modal p{color:#8b949e;font-size:12px;overflow-wrap:anywhere}.translation-file-browser-controls{justify-content:space-between}.translation-file-browser-search{flex:1 1 320px;justify-content:flex-end}.translation-file-browser-search input{flex:1 1 180px;min-width:0}.translation-file-browser-modal button,.translation-file-browser-modal input{border:1px solid #3a4149;border-radius:6px;background:#111820;color:#d6deeb;min-height:30px;padding:4px 8px;font:inherit;font-size:12px}.translation-file-browser-modal button:hover:not(:disabled){border-color:#58a6ff;background:#162235}.translation-file-browser-layout{display:grid;grid-template-columns:minmax(260px,1fr) minmax(220px,.42fr);gap:10px;min-height:0;min-width:0;overflow:hidden}.translation-file-browser-list,.translation-file-browser-selection{min-height:0;min-width:0;overflow:auto;border:1px solid #292d31;border-radius:6px;background:#0b0f14;padding:10px}.translation-file-browser-group{display:grid;align-content:start;gap:6px;margin-bottom:12px}.translation-file-browser-entry{display:grid;grid-template-columns:38px minmax(0,1fr);gap:3px 8px;width:100%;min-width:0;text-align:left}.translation-file-browser-entry span{grid-row:span 2;align-self:center;color:#8b949e;font-size:11px}.translation-file-browser-entry strong,.translation-file-browser-entry small{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.translation-file-browser-entry small{color:#8b949e}.translation-file-browser-entry.is-selected{border-color:#58a6ff;background:#142033}.translation-file-browser-selection{display:grid;align-content:start;gap:12px}.translation-file-browser-selection label{display:grid;gap:5px}.translation-file-browser-selection span{color:#8b949e;font-size:12px}.translation-file-browser-selection input{width:100%;min-width:0}.translation-panel-header{display:grid;flex:0 0 auto;gap:3px}.translation-panel-titlebar,.translation-panel-actions,.translation-status-row{display:flex;flex-wrap:wrap;gap:6px;align-items:center;justify-content:space-between}.translation-panel-header h2,.translation-panel-header p{margin-bottom:0}.translation-panel-titlebar h2{font-size:16px}.translation-panel-header p,.translation-composer span{color:#8b949e;font-size:12px}.translation-panel-actions button{border-color:#3a4149;background:#161b22;color:#d6deeb;min-height:26px;padding:2px 8px;font-size:12px}.translation-panel-actions button:hover:not(:disabled),.translation-composer-actions button:hover:not(:disabled){border-color:#58a6ff;background:#1f2937}.translation-panel-actions{justify-content:flex-end}.translation-entry-list{display:grid;flex:1 1 auto;align-content:start;gap:8px;min-height:0;min-width:0;overflow-x:hidden;overflow-y:auto;scrollbar-color:#4b5563 #0d1117}.translation-entry{border:0;border-radius:0;background:transparent;min-width:0;max-width:100%;padding:0}.translation-conversation-boundary{display:grid;grid-template-columns:minmax(18px,1fr) auto auto auto minmax(18px,1fr);gap:8px;align-items:center;color:#8b949e;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px;line-height:1.4;white-space:nowrap}.translation-boundary-dash{min-width:0;border-top:1px dashed #3a4149}.translation-entry.is-user-input{border-top:4px solid #3a4149;margin-top:14px;padding-top:14px}.translation-entry.is-user-input:first-child{margin-top:0}.translation-entry pre{box-sizing:border-box;margin:0;max-height:none;max-width:100%;min-width:0;overflow:visible;white-space:pre-wrap;overflow-wrap:anywhere;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px;line-height:1.45;color:#d6deeb}.translation-markdown{max-width:100%;min-width:0;color:#d6deeb;font-size:12px;line-height:1.55;overflow-wrap:anywhere}.translation-markdown>:first-child{margin-top:0}.translation-markdown>:last-child{margin-bottom:0}.translation-markdown p,.translation-markdown ul,.translation-markdown ol,.translation-markdown blockquote,.translation-markdown pre,.translation-markdown table{margin:0 0 8px}.translation-markdown h1,.translation-markdown h2,.translation-markdown h3,.translation-markdown h4,.translation-markdown h5,.translation-markdown h6{margin:10px 0 6px;color:#f0f6fc;font-weight:700;line-height:1.25}.translation-markdown h1{font-size:17px}.translation-markdown h2{font-size:15px}.translation-markdown h3,.translation-markdown h4,.translation-markdown h5,.translation-markdown h6{font-size:13px}.translation-markdown ul,.translation-markdown ol{padding-left:22px}.translation-markdown li{margin:2px 0}.translation-markdown .task-list-item{list-style:none}.translation-markdown input[type=checkbox]{width:13px;height:13px;margin:0 6px 0 0;accent-color:#56d364}.translation-markdown blockquote{border-left:3px solid #3a4149;color:#b7c0ca;padding-left:10px}.translation-markdown a{color:#79c0ff}.translation-markdown code{border-radius:4px;background:#161b22;color:#f0f6fc;padding:1px 4px;font-family:Menlo,Monaco,Consolas,monospace;font-size:.95em}.translation-markdown pre{overflow-x:auto;border:1px solid #292d31;border-radius:6px;background:#111316;padding:8px;white-space:pre}.translation-markdown pre code{background:transparent;padding:0}.translation-markdown table{display:block;max-width:100%;overflow-x:auto;border-collapse:collapse}.translation-markdown img{max-width:100%;border-radius:4px}.translation-markdown th,.translation-markdown td{border:1px solid #30363d;padding:4px 6px;text-align:left;vertical-align:top}.translation-markdown hr{border:0;border-top:1px solid #292d31;margin:10px 0}.translation-entry.is-tool-output pre{display:block;overflow:hidden;color:#7d8590;text-overflow:ellipsis;white-space:nowrap;width:100%}.translation-entry-note{margin:2px 0 0;color:#6e7681;font-size:10px;line-height:1.35}.translation-entry-note.is-error{color:#a3715f}.translation-manual-panel{display:grid;flex:0 0 auto;gap:6px;border-bottom:1px solid #292d31;padding-bottom:8px}.translation-composer{display:grid;flex:0 0 auto;gap:6px;border-top:1px solid #292d31;padding-top:8px}.translation-composer-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:stretch}.translation-manual-panel textarea,.translation-composer textarea{width:100%;min-height:38px;max-height:88px;border-color:#3a4149;background:#0d1117;color:#d6deeb;font-family:inherit;font-size:12px;line-height:1.35;resize:vertical}.translation-manual-panel textarea::placeholder,.translation-composer textarea::placeholder{color:#7d8590}.translation-manual-panel textarea::selection,.translation-composer textarea::selection{background:#8b949e59;color:#fff}.translation-manual-panel textarea:focus,.translation-manual-panel textarea:focus-visible,.translation-composer textarea:focus,.translation-composer textarea:focus-visible{border-color:#4b5563;outline:none;box-shadow:none}.translation-composer-actions{display:grid;align-content:start;gap:6px;min-width:104px}.translation-composer-actions button{border-color:#3a4149;background:#161b22;color:#d6deeb;width:100%;min-height:38px;padding:4px 9px;font-size:12px}.translation-panel .muted{color:#8b949e}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:20;display:grid;place-items:center;background:#181c1f61;padding:18px}.translator-session-backdrop{background:#010409b8}.translator-session-modal{display:grid;grid-template-rows:auto auto minmax(0,1fr);gap:10px;width:95vw;height:92vh;min-width:0;min-height:0;border:1px solid #30363d;border-radius:8px;background:#0d1117;color:#d6deeb;padding:10px}.translator-session-header{display:flex;gap:10px;align-items:center;justify-content:space-between;min-width:0}.translator-session-header h2,.translator-session-header p{margin-bottom:0}.translator-session-header p{color:#8b949e;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px}.translator-session-terminal{min-width:0;min-height:0;border-radius:6px;overflow:hidden;background:#111316}.usage-analytics-backdrop{background:#181c1f85}.usage-analytics-modal{display:grid;grid-template-rows:auto auto minmax(0,1fr);gap:12px;width:min(94vw,1280px);height:min(90vh,900px);min-width:0;min-height:0;overflow:hidden;border:1px solid #c8c0b4;border-radius:8px;background:#fffdfa;color:#1c2024;padding:14px;box-shadow:0 22px 64px #23282b3d}.usage-analytics-header,.usage-analytics-header-actions,.usage-analytics-meta{display:flex;align-items:center}.usage-analytics-header{justify-content:space-between;gap:16px}.usage-analytics-header h2,.usage-analytics-header p{margin-bottom:0}.usage-analytics-header p,.usage-analytics-meta,.usage-analytics-table small,.usage-analytics-no-models,.usage-analytics-empty{color:#667071}.usage-analytics-header-actions{gap:8px}.usage-analytics-content{min-width:0;min-height:0;overflow:auto;padding-right:2px}.usage-analytics-meta{justify-content:space-between;gap:12px;margin-bottom:14px;font-size:12px}.usage-analytics-section+.usage-analytics-section{margin-top:18px}.usage-analytics-section h3{margin:0 0 8px;font-size:13px}.usage-totals-grid{display:grid;grid-template-columns:repeat(5,minmax(140px,1fr));gap:8px;margin:0}.usage-totals-grid div{min-width:0;border:1px solid #ddd5c8;border-radius:6px;background:#f8f7f2;padding:10px}.usage-totals-grid dt{color:#667071;font-size:11px;font-weight:650}.usage-totals-grid dd{margin:3px 0 0;color:#1c2024;font-family:Menlo,Monaco,Consolas,monospace;font-size:16px;font-weight:750}.usage-analytics-table-wrap{width:100%;overflow-x:auto;border:1px solid #ddd5c8;border-radius:6px}.usage-analytics-table{width:100%;min-width:860px;border-collapse:collapse;font-size:12px}.usage-analytics-table th,.usage-analytics-table td{border-bottom:1px solid #e7e0d5;padding:8px 10px;text-align:right;white-space:nowrap}.usage-analytics-table thead th{background:#f2efe8;color:#596365;font-size:11px;font-weight:700}.usage-analytics-table th:first-child{position:sticky;left:0;z-index:1;min-width:190px;background:#fffdfa;text-align:left}.usage-analytics-table thead th:first-child{z-index:2;background:#f2efe8}.usage-analytics-table tbody tr:last-child th,.usage-analytics-table tbody tr:last-child td{border-bottom:0}.usage-analytics-table tbody th span,.usage-analytics-table tbody th small{display:block}.usage-analytics-table tbody th small{margin-top:2px;font-weight:500}.usage-analytics-table td{font-family:Menlo,Monaco,Consolas,monospace}.usage-analytics-error{margin:0}.usage-analytics-no-models,.usage-analytics-empty{margin:0;padding:24px 8px;text-align:center}@media(max-width:900px){.usage-analytics-modal{width:96vw;height:94vh;padding:10px}.usage-analytics-header,.usage-analytics-meta{align-items:flex-start;flex-direction:column}.usage-totals-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}.harness-studio-backdrop{background:#010409b8}.harness-studio-modal{display:grid;grid-template-rows:auto minmax(0,1fr);gap:12px;width:96vw;height:94vh;min-width:0;min-height:0;overflow:hidden;border:1px solid #30363d;border-radius:8px;background:#0d1117;color:#d6deeb;padding:12px}.harness-studio-header{display:flex;gap:12px;align-items:center;justify-content:space-between;min-width:0}.harness-studio-header h2,.harness-studio-header p{margin-bottom:0}.harness-studio-header p{color:#8b949e}.harness-studio-header-actions{display:flex;gap:8px;align-items:center}.harness-studio-layout{display:grid;grid-template-columns:minmax(340px,.85fr) minmax(640px,1.55fr);gap:12px;height:100%;min-width:0;min-height:0;overflow:hidden}.harness-studio-left{display:grid;grid-template-rows:minmax(0,1fr);min-width:0;min-height:0;height:100%;max-height:100%;overflow:hidden}.harness-studio-left-scroll{display:grid;grid-auto-rows:max-content;align-content:start;gap:10px;min-width:0;min-height:0;height:100%;max-height:100%;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;scrollbar-gutter:stable;padding-right:2px}.harness-studio-left-preview{grid-template-rows:minmax(0,1fr);height:100%;align-content:stretch;overflow:hidden;padding-right:0}.harness-studio-section{min-width:0;border:1px solid #30363d;border-radius:6px;background:#0b1017;padding:10px}.harness-studio-section h3{margin-bottom:8px;font-size:14px}.harness-studio-collapsible-section{padding:0;overflow:hidden}.harness-studio-collapsible-section summary{display:flex;gap:8px;align-items:center;justify-content:space-between;padding:10px;cursor:pointer;list-style:none}.harness-studio-collapsible-section summary::-webkit-details-marker{display:none}.harness-studio-collapsible-section summary h3{margin:0}.harness-studio-collapsible-section summary span{color:#8b949e;font-size:11px}.harness-studio-collapsible-section[open] summary span{color:#d6deeb}.harness-studio-collapsible-content{padding:0 10px 10px}.harness-studio-engineer{display:grid;grid-template-rows:auto auto minmax(0,1fr);gap:8px;min-height:0}.harness-studio-engineer-header{display:flex;gap:10px;align-items:flex-start;justify-content:space-between;min-width:0}.harness-studio-engineer-header p{margin-bottom:0}.harness-studio-file-preview{display:grid;grid-template-rows:auto auto auto minmax(0,1fr);gap:10px;height:100%;min-width:0;min-height:0;overflow:hidden}.harness-studio-file-editor-header{display:flex;gap:10px;align-items:flex-start;justify-content:space-between;min-width:0}.harness-studio-file-editor-header p{margin-bottom:0}.harness-studio-file-editor-header h3,.harness-studio-file-editor-header p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.harness-studio-file-editor-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;align-items:center}.harness-studio-file-textarea{grid-row:4;align-self:stretch;height:100%;width:100%;min-width:0;min-height:0;overflow:auto;resize:none;border:1px solid #30363d;border-radius:6px;background:#090d13;color:#d6deeb;padding:10px;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px;line-height:1.55}.harness-studio-file-textarea:read-only{background:#080c12;color:#8b949e;cursor:default}.harness-studio-file-textarea.is-editing{background:#090d13;color:#d6deeb;cursor:text}.harness-studio-file-textarea:disabled{opacity:.72}.harness-engineer-terminal{min-width:0;min-height:0;overflow:hidden;border-radius:6px;background:#111316}.harness-studio-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px}.harness-studio-metric{display:grid;gap:4px;min-width:0;border:1px solid #30363d;border-radius:6px;padding:8px}.harness-studio-metric span{color:#8b949e;font-size:11px}.harness-studio-metric strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.harness-studio-file-list,.harness-studio-doc-list{display:grid;gap:6px;margin:0;padding:0;list-style:none}.harness-studio-file-list li,.harness-studio-doc-list li{display:grid;gap:8px;align-items:center;min-width:0;border:1px solid #30363d;border-radius:6px;padding:8px}.harness-studio-file-list li,.harness-studio-doc-list li{grid-template-columns:minmax(0,1fr) auto auto}.harness-studio-code-intelligence-list li{grid-template-columns:minmax(0,.7fr) minmax(0,.8fr) minmax(0,.7fr) auto minmax(0,1.5fr)}.harness-studio-code-intelligence-list code{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.harness-studio-code-intelligence-detail{min-width:0;color:#8b949e;overflow-wrap:anywhere}.harness-studio-doc-list button{padding:4px 8px}.harness-studio-file-list li.selected{border-color:#58a6ff;background:#0f1b2d}.harness-studio-file-list button{min-width:0;overflow:hidden;border:0;background:transparent;color:inherit;padding:0;text-align:left;text-overflow:ellipsis;white-space:nowrap}.harness-studio-file-list .harness-studio-file-copy-button{border:1px solid #30363d;border-radius:5px;background:#161b22;color:#d6deeb;padding:4px 8px;text-align:center}.harness-studio-file-list .harness-studio-file-copy-button:hover{border-color:#58a6ff}.harness-studio-file-list span:first-child,.harness-studio-doc-list span:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.harness-memory-status{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:10px}.harness-memory-status .warnings{flex-basis:100%;margin:0}.harness-memory-runs{margin-top:12px}.harness-memory-runs h4{margin:0 0 8px;font-size:12px}.harness-studio-file-list .harness-memory-action-button,.harness-memory-action-button{border:1px solid #3d444d;border-radius:5px;background:#161b22;padding:4px 8px;text-align:center}.repository-diff-backdrop{background:#010409b8}.repository-diff-modal{display:grid;grid-template-rows:auto auto auto minmax(0,1fr);gap:10px;width:96vw;height:94vh;min-width:0;min-height:0;overflow:hidden;border:1px solid #30363d;border-radius:8px;background:#0d1117;color:#d6deeb;padding:12px}.repository-diff-header{display:flex;gap:12px;align-items:center;justify-content:space-between;min-width:0}.repository-diff-header h2,.repository-diff-header p,.repository-diff-file-header h3,.repository-diff-file-header p{margin-bottom:0}.repository-diff-header p,.repository-diff-file-header p{color:#8b949e}.repository-diff-header-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:flex-end}.repository-diff-commit-picker{display:inline-flex;gap:8px;align-items:center;min-width:280px}.repository-diff-commit-picker span{color:#8b949e;font-size:12px;font-weight:700}.repository-diff-commit-picker select{min-width:260px;max-width:520px}.repository-diff-warnings{margin-top:0}.repository-diff-body{display:grid;grid-template-columns:minmax(280px,.32fr) minmax(0,1fr);gap:10px;min-width:0;min-height:0}.repository-diff-sidebar,.repository-diff-main{min-width:0;min-height:0;border:1px solid #30363d;border-radius:6px;background:#0b1017}.repository-diff-sidebar{display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden}.repository-diff-summary{display:grid;gap:4px;border-bottom:1px solid #30363d;padding:10px;font-size:12px}.repository-diff-summary span{color:#8b949e}.repository-diff-file-list{display:grid;align-content:start;gap:6px;min-width:0;margin:0;padding:10px;overflow:auto;list-style:none}.repository-diff-file-list li{min-width:0}.repository-diff-file-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:stretch;min-width:0}.repository-diff-file-list button{display:grid;gap:4px;width:100%;min-width:0;border:1px solid #30363d;border-radius:6px;background:transparent;color:inherit;padding:8px;text-align:left}.repository-diff-file-list li.selected .repository-diff-file-select,.repository-diff-file-list li.task-diff-selected .repository-diff-task-file-button{border-color:#58a6ff;background:#0f1b2d}.repository-diff-task-file-button{align-content:center;min-width:78px;font-size:12px;text-align:center}.repository-diff-file-list span,.repository-diff-file-list small{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.repository-diff-file-list small{color:#8b949e}.repository-diff-empty{color:#8b949e;font-size:13px}.repository-diff-main{display:grid;grid-template-rows:auto auto auto minmax(0,1fr);gap:8px;overflow:hidden;padding:10px}.repository-diff-file-header{display:flex;gap:10px;align-items:flex-start;justify-content:space-between;min-width:0}.repository-diff-file-header h3{overflow-wrap:anywhere;font-size:15px}.repository-diff-stats{flex:0 0 auto;color:#7ee787;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px}.repository-diff-task-file-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:flex-end}.repository-diff-code{min-width:0;min-height:0;margin:0;overflow:auto;border:1px solid #30363d;border-radius:6px;background:#090d13;color:#d6deeb;padding:0;font-family:Menlo,Monaco,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre}.repository-diff-line{display:block;min-width:max-content;border-left:3px solid transparent;padding:0 12px}.repository-diff-line-context{color:#c9d1d9}.repository-diff-line-added{border-left-color:#3fb950;background:#2ea04333;color:#aff5b4}.repository-diff-line-deleted{border-left-color:#f85149;background:#f851492e;color:#ffdcd7}.repository-diff-line-hunk{border-left-color:#58a6ff;background:#388bfd29;color:#79c0ff}.repository-diff-placeholder{display:grid;place-items:center;min-height:240px;color:#8b949e}.gateway-qr-modal{display:grid;grid-template-rows:auto minmax(0,1fr);gap:14px;width:min(520px,100%);max-height:min(720px,92vh);overflow:auto;border:1px solid #d6d0c6;border-radius:8px;background:#fffdf8;padding:16px}.message-modal,.event-modal{display:grid;grid-template-rows:auto minmax(0,1fr);gap:12px;width:min(980px,100%);max-height:min(760px,92vh);overflow:hidden;border:1px solid #d6d0c6;border-radius:8px;background:#fffdf8;padding:14px}.gateway-qr-modal header,.message-modal header,.event-modal header{display:flex;gap:8px;align-items:center;justify-content:space-between}.gateway-qr-modal h2,.gateway-qr-modal p{margin-bottom:0}.gateway-qr-modal-body{display:grid;gap:14px;justify-items:center}.gateway-qr-code-frame{display:grid;place-items:center;width:min(360px,100%);aspect-ratio:1;border:1px solid #d6d0c6;border-radius:8px;background:#fff;padding:18px}.gateway-qr-code-frame img{display:block;width:100%;height:auto}.gateway-qr-actions{display:flex;justify-content:flex-end;width:min(360px,100%)}.gateway-qr-placeholder{color:#667071;text-align:center}.gateway-qr-meta{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;width:100%;margin:0}.gateway-qr-meta div{min-width:0;border:1px solid #ece5d9;border-radius:6px;padding:8px}.gateway-qr-meta dt{color:#6c6255;font-size:11px;font-weight:700;text-transform:uppercase}.gateway-qr-meta dd{margin:0;overflow-wrap:anywhere;font-size:13px}.gateway-manual-bind{display:grid;grid-template-columns:repeat(2,minmax(0,1fr)) auto;align-items:end;gap:10px;width:100%;border-top:1px solid #ece5d9;padding-top:12px}.gateway-manual-bind div{display:grid;gap:4px}.gateway-manual-bind label{color:#6c6255;font-size:12px;font-weight:700}.gateway-manual-bind input{width:100%;border:1px solid #d6d0c6;border-radius:6px;background:#fff;color:#191713;padding:8px 10px;font:inherit}.form-error{grid-column:1 / -1;color:#b42318;font-size:13px}.message-modal h2,.message-modal p,.event-modal h2,.event-modal p{margin-bottom:0}.translation-test-result{border-radius:6px;padding:8px;font-size:13px}.translation-test-result.is-ok{border:1px solid #6ea77e;background:#e6f3e9;color:#245334}.translation-test-result.is-error{border:1px solid #c46e5f;background:#fae9e6;color:#6f2b21}.message-panel{display:grid;gap:8px}.message-modal .message-panel,.event-modal .event-log{min-height:0;overflow:auto;border:0;background:transparent;padding:0}.message-panel-header{display:flex;justify-content:space-between;gap:12px;align-items:center}.message-panel-header h2,.message-panel-header p{margin-bottom:0}.message-controls,.message-mode-toggle,.modal-actions,.message-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.message-mode-toggle{width:auto;min-width:220px;font-size:13px}.message-list{display:grid;gap:8px;margin:0;padding:0;list-style:none}.message-item{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:start;border:1px solid #ece5d9;border-radius:6px;padding:8px;background:#fffdfa}.message-meta{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:4px}.message-meta time,.message-meta span:not(.status-badge),.message-reason,.message-path{color:#667071;font-size:12px}.message-sequence{min-width:32px;color:#1f242b;font-weight:800}.message-actions button{min-height:30px;padding:4px 10px}.message-item p{display:-webkit-box;margin-bottom:4px;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:2}.message-reason,.message-path{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.event-log ol{margin:0;padding-left:22px;font-size:13px}.event-log{max-height:92px;overflow:auto}.event-log h2{margin-bottom:4px;font-size:13px}.event-log p{margin-bottom:0}.event-log li{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.status-badge{display:inline-flex;align-items:center;justify-content:center;min-width:66px;min-height:20px;border-radius:999px;padding:2px 8px;border:1px solid #c7c1b8;background:#f2eee7;color:#4f5558;font-size:11px;white-space:nowrap}.status-active,.status-running,.status-ok{border-color:#6ea77e;background:#e6f3e9;color:#245334}.status-created,.status-idle,.status-disabled{border-color:#9aa3a8;background:#edf0f1;color:#465056}.status-blocked,.status-crashed,.status-missing,.status-empty,.status-delete{border-color:#c46e5f;background:#fae9e6;color:#6f2b21}.status-waiting,.status-starting,.status-incomplete,.status-outdated{border-color:#c4a34e;background:#f7efcf;color:#604e16}.status-exited,.status-done,.status-stopped,.status-resumable,.status-skipped,.status-overridden,.status-not_required{border-color:#7b98b8;background:#e9f0f8;color:#2e4e70}.status-queued,.status-translating,.status-ready,.status-create,.status-insert,.status-update{border-color:#c4a34e;background:#f7efcf;color:#604e16}.status-rejected,.status-failed,.status-delivery_failed,.status-response_ready_missing_result,.status-cancelled,.status-blocked{border-color:#c46e5f;background:#fae9e6;color:#6f2b21}.status-pending{border-color:#c7c1b8;background:#f2eee7;color:#4f5558}.status-translated,.status-preserved{border-color:#7b98b8;background:#e9f0f8;color:#2e4e70}.empty-workspace{max-width:680px}@media(max-width:980px){.app-shell,.workspace-grid{grid-template-columns:1fr}.app-sidebar{border-right:0;border-bottom:1px solid #d3c9b8}.role-tabs{grid-template-columns:repeat(2,minmax(0,1fr))}.session-console-body.has-translation,.translation-file-browser-layout{grid-template-columns:1fr}.session-controls,.session-toolbar{flex-wrap:wrap;overflow:visible}.harness-studio-code-intelligence-list li{grid-template-columns:minmax(0,1fr) auto}.harness-studio-code-intelligence-list code,.harness-studio-code-intelligence-detail{grid-column:1 / -1}.file-translation-modal{width:95vw;height:95vh;padding:10px}.file-translation-layout{grid-template-columns:minmax(180px,240px) minmax(0,1fr)}.translation-file-browser-modal{min-height:0}}@media(max-width:700px){.workspace-runtime-warning{grid-template-columns:1fr;gap:4px}.file-translation-layout{grid-template-columns:1fr;grid-template-rows:minmax(140px,28vh) minmax(0,1fr)}.file-translation-header{align-items:stretch}.file-translation-toolbar{width:100%}.file-translation-toolbar button{flex:1 1 auto}}@media(max-width:560px){.app-main,.app-sidebar{padding:12px}.workspace-header,.inline-form,.inline-form.has-recent-paths{grid-template-columns:1fr;display:grid}.role-tabs{grid-template-columns:1fr}.terminal-frame-shell,.terminal-empty{min-height:300px;height:54vh}.session-option-field{grid-template-columns:1fr;width:100%}.translation-file-browser-modal{width:calc(100vw - 20px);max-height:calc(100vh - 20px);padding:10px}.file-translation-modal{width:calc(100vw - 12px);height:calc(100vh - 12px)}.translation-file-browser-controls,.translation-file-browser-search{display:grid;grid-template-columns:1fr}.gateway-manual-bind{grid-template-columns:1fr}.gateway-manual-bind button{justify-self:stretch}}.harness-bootstrap-terminal .terminal-frame-shell{height:100%;min-height:0}:root[data-theme=dark]{color-scheme:dark;background:#0d1117;color:#e6edf3}:root[data-theme=dark] body,:root[data-theme=dark] .app-main{background:#0d1117;color:#e6edf3}:root[data-theme=dark] button{border-color:#3d4652;background:#161b22;color:#e6edf3}:root[data-theme=dark] button:hover:not(:disabled){border-color:#58a6ff;background:#1f2937}:root[data-theme=dark] input,:root[data-theme=dark] select,:root[data-theme=dark] textarea:not(.xterm-helper-textarea){border-color:#3d4652;background:#0d1117;color:#e6edf3}:root[data-theme=dark] input::placeholder,:root[data-theme=dark] textarea::placeholder{color:#7d8590}:root[data-theme=dark] .danger-button{border-color:#da7b72;background:#2d1518;color:#ffdcd7}:root[data-theme=dark] .danger-button:hover:not(:disabled){border-color:#ffa198;background:#3d1f23}:root[data-theme=dark] .app-sidebar{border-color:#30363d;background:#0f141b}:root[data-theme=dark] .sidebar-toggle{background:#161b22}:root[data-theme=dark] .brand-header span,:root[data-theme=dark] .muted,:root[data-theme=dark] .message-meta time,:root[data-theme=dark] .message-meta span:not(.status-badge),:root[data-theme=dark] .message-reason,:root[data-theme=dark] .message-path{color:#8b949e}:root[data-theme=dark] .sidebar-section,:root[data-theme=dark] .session-console,:root[data-theme=dark] .message-panel,:root[data-theme=dark] .event-log,:root[data-theme=dark] .empty-workspace,:root[data-theme=dark] .gateway-qr-modal,:root[data-theme=dark] .message-modal,:root[data-theme=dark] .event-modal{border-color:#30363d;background:#11161d}:root[data-theme=dark] .gateway-qr-code-frame,:root[data-theme=dark] .gateway-qr-meta div,:root[data-theme=dark] .gateway-manual-bind input{border-color:#30363d;background:#0d1117}:root[data-theme=dark] .gateway-qr-code-frame{background:#f6f8fa}:root[data-theme=dark] .gateway-qr-meta dt,:root[data-theme=dark] .gateway-qr-placeholder,:root[data-theme=dark] .gateway-manual-bind label{color:#8b949e}:root[data-theme=dark] .sidebar-section-toggle{color:#e6edf3}:root[data-theme=dark] .sidebar-section-toggle:hover{background:#161b22}:root[data-theme=dark] .sidebar-section-toggle[aria-expanded=true]{border-color:#30363d}:root[data-theme=dark] .project-summary dt,:root[data-theme=dark] .session-option-field span,:root[data-theme=dark] .message-mode-toggle{color:#b7c0ca}:root[data-theme=dark] .session-option-field small,:root[data-theme=dark] .task-create-preview small{color:#8b949e}:root[data-theme=dark] .warnings{border-color:#da7b72;background:#2d1518;color:#ffdcd7}:root[data-theme=dark] .workspace-runtime-warning{border-color:#da7b72;background:#2d1518;color:#ffdcd7}:root[data-theme=dark] .ui-error-center{border-color:#da7b72;background:#2d1518;color:#ffdcd7;box-shadow:0 18px 50px #0104098f}:root[data-theme=dark] .ui-error-center-header p,:root[data-theme=dark] .ui-error-list span{color:#ffb4ab}:root[data-theme=dark] .ui-error-center button{border-color:#da7b72;color:#ffdcd7}:root[data-theme=dark] .ui-error-list li{border-top-color:#da7b7257}:root[data-theme=dark] .success-banner{border-color:#3fb950;background:#112718;color:#aff5b4}:root[data-theme=dark] .flow-pause-alert-backdrop{background:#010409b8}:root[data-theme=dark] .flow-pause-alert{border-color:#56d4dd;background:#10262b;color:#d6fbff;box-shadow:0 28px 72px #0104099e}:root[data-theme=dark] .flow-pause-alert-kicker,:root[data-theme=dark] .flow-pause-alert-hint{color:#9debf2}:root[data-theme=dark] .flow-pause-alert button{border-color:#56d4dd;background:#56d4dd;color:#061114}:root[data-theme=dark] .flow-pause-alert button:hover{background:#84f3fa}:root[data-theme=dark] .role-recovery-toast{border-color:#d29922;background:#2d230d;color:#ffdf8b;box-shadow:0 14px 42px #01040985}:root[data-theme=dark] .role-recovery-toast button{border-color:#d29922;color:#ffdf8b}:root[data-theme=dark] .harness-file-list li,:root[data-theme=dark] .harness-changes,:root[data-theme=dark] .harness-result,:root[data-theme=dark] .gateway-qr img,:root[data-theme=dark] .task-create-preview,:root[data-theme=dark] .task-status-stats div,:root[data-theme=dark] .current-round-status,:root[data-theme=dark] .message-item{border-color:#30363d;background:#0d1117}:root[data-theme=dark] .harness-bootstrap-modal{background:#010409b8}:root[data-theme=dark] .harness-bootstrap-modal-surface{border-color:#30363d;background:#0d1117;box-shadow:0 22px 64px #0104099e}:root[data-theme=dark] .harness-bootstrap-controls label span{color:#b7c0ca}:root[data-theme=dark] .harness-bootstrap-controls select{border-color:#3a4149;background:#0d1117;color:#d6deeb}:root[data-theme=dark] .task-create-option{color:#e6edf3}:root[data-theme=dark] .task-status-dock{border-color:#30363d}:root[data-theme=dark] .task-create-preview span{color:#7ee787}:root[data-theme=dark] .task-status-stats dt{color:#8b949e}:root[data-theme=dark] .task-status-stats dd,:root[data-theme=dark] .current-round-title span:first-child{color:#e6edf3}:root[data-theme=dark] .message-sequence{color:#f0f6fc}:root[data-theme=dark] .settings-help-text{color:#d29922}:root[data-theme=dark] .task-nav-item.is-active,:root[data-theme=dark] .role-tab.is-active,:root[data-theme=dark] .sidebar-settings .settings-toggle.is-active,:root[data-theme=dark] .gateway-actions .settings-toggle.is-active{border-color:#56d4dd;background:#10262b;color:#d6fbff}:root[data-theme=dark] .switch-control{border-color:#3d4652;background:#161b22;color:#d6deeb}:root[data-theme=dark] .switch-control:hover:not(:disabled){border-color:#56d4dd;background:#1a2530}:root[data-theme=dark] .switch-control-track{background:#3d4652}:root[data-theme=dark] .switch-control-thumb{background:#e6edf3;box-shadow:0 1px 4px #0104097a}:root[data-theme=dark] .switch-control.is-on{border-color:#56d4dd;background:#10262b;color:#d6fbff}:root[data-theme=dark] .switch-control.is-on .switch-control-track{background:#56d4dd}:root[data-theme=dark] .session-option-field select,:root[data-theme=dark] .settings-select-row select,:root[data-theme=dark] .codex-bridge-api-key-form input{border-color:#3d4652;background:#0d1117;color:#e6edf3}:root[data-theme=dark] .settings-select-row{color:#b7c0ca}:root[data-theme=dark] .codex-bridge-settings{border-top-color:#30363d}:root[data-theme=dark] .codex-bridge-api-key-form{color:#b7c0ca}:root[data-theme=dark] .settings-status-row{border-color:#3d4652;background:#161b22;color:#d6deeb}:root[data-theme=dark] .settings-status-row strong{color:#e6edf3}:root[data-theme=dark] .terminal-empty{border-color:#30363d}:root[data-theme=dark] .modal-backdrop{background:#010409b8}:root[data-theme=dark] .message-modal .message-panel,:root[data-theme=dark] .event-modal .event-log{background:transparent}:root[data-theme=dark] .usage-analytics-modal{border-color:#30363d;background:#0d1117;color:#e6edf3;box-shadow:0 22px 64px #0104099e}:root[data-theme=dark] .usage-analytics-header p,:root[data-theme=dark] .usage-analytics-meta,:root[data-theme=dark] .usage-analytics-table small,:root[data-theme=dark] .usage-analytics-no-models,:root[data-theme=dark] .usage-analytics-empty,:root[data-theme=dark] .usage-totals-grid dt{color:#8b949e}:root[data-theme=dark] .usage-totals-grid div,:root[data-theme=dark] .usage-analytics-table-wrap{border-color:#30363d;background:#161b22}:root[data-theme=dark] .usage-totals-grid dd{color:#f0f6fc}:root[data-theme=dark] .usage-analytics-table th,:root[data-theme=dark] .usage-analytics-table td{border-bottom-color:#30363d}:root[data-theme=dark] .usage-analytics-table thead th,:root[data-theme=dark] .usage-analytics-table thead th:first-child{background:#161b22;color:#b7c0ca}:root[data-theme=dark] .usage-analytics-table tbody th:first-child{background:#0d1117}:root[data-theme=dark] .status-badge{border-color:#3d4652;background:#161b22;color:#d6deeb}:root[data-theme=dark] .translation-test-result.is-ok,:root[data-theme=dark] .status-active,:root[data-theme=dark] .status-running,:root[data-theme=dark] .status-ok{border-color:#3fb950;background:#12261a;color:#aff5b4}:root[data-theme=dark] .status-created,:root[data-theme=dark] .status-idle,:root[data-theme=dark] .status-disabled{border-color:#69717d;background:#20262f;color:#d6deeb}:root[data-theme=dark] .translation-test-result.is-error,:root[data-theme=dark] .status-blocked,:root[data-theme=dark] .status-crashed,:root[data-theme=dark] .status-missing,:root[data-theme=dark] .status-empty,:root[data-theme=dark] .status-delete,:root[data-theme=dark] .status-rejected,:root[data-theme=dark] .status-failed,:root[data-theme=dark] .status-delivery_failed,:root[data-theme=dark] .status-response_ready_missing_result,:root[data-theme=dark] .status-cancelled{border-color:#f85149;background:#2d1518;color:#ffdcd7}:root[data-theme=dark] .status-waiting,:root[data-theme=dark] .status-starting,:root[data-theme=dark] .status-incomplete,:root[data-theme=dark] .status-queued,:root[data-theme=dark] .status-translating,:root[data-theme=dark] .status-ready,:root[data-theme=dark] .status-create,:root[data-theme=dark] .status-insert,:root[data-theme=dark] .status-update{border-color:#d29922;background:#2d2208;color:#f8e3a1}:root[data-theme=dark] .status-exited,:root[data-theme=dark] .status-done,:root[data-theme=dark] .status-stopped,:root[data-theme=dark] .status-resumable,:root[data-theme=dark] .status-skipped,:root[data-theme=dark] .status-overridden,:root[data-theme=dark] .status-not_required,:root[data-theme=dark] .status-translated,:root[data-theme=dark] .status-preserved{border-color:#388bfd;background:#10223a;color:#c9e2ff}:root[data-theme=dark] .status-pending{border-color:#3d4652;background:#161b22;color:#d6deeb}
|