diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 07fd1d1cf6b..7e4c10e1607 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -4,7 +4,7 @@ contact_links:
url: https://github.com/lidge-jun/opencodex/security/advisories/new
about: Report undisclosed vulnerabilities privately to the maintainers. Do not open a public issue.
- name: Security policy
- url: https://github.com/lidge-jun/opencodex/blob/main/SECURITY.md
+ url: https://github.com/lidge-jun/opencodex/blob/dev/SECURITY.md
about: Read the supported-version and reporting guidance before sharing security-sensitive details.
- name: Contributing guide
url: https://opencodex.me/contributing/
diff --git a/.github/scripts/enforce-pr-target.test.cjs b/.github/scripts/enforce-pr-target.test.cjs
index 3fc9c675daa..9756869eb91 100644
--- a/.github/scripts/enforce-pr-target.test.cjs
+++ b/.github/scripts/enforce-pr-target.test.cjs
@@ -165,24 +165,23 @@ describe("enforce-pr-target workflow", () => {
.split("- name: Checkout trusted PR-quality scripts")[1]
.split(/\n {6}- name:/)[0];
assert.match(checkoutStep, /actions\/checkout@[0-9a-f]{40}/);
- // The trusted ref comes from a fixed set of integration branches, never
- // from the PR's own base commit: a stacked child's base is another open
- // PR's head, and `base.sha` would let that unpromoted commit choose the
- // code that runs with this job's write-capable token.
+ // The trusted ref is the single integration branch, never the PR's own
+ // base commit: a stacked child's base is another open PR's head, and
+ // `base.sha` would let that unpromoted commit choose the code that runs
+ // with this job's write-capable token.
//
// `status` has no pull_request payload and sources from the default branch
- // that supplied the privileged workflow. A `main`-targeting PR sources
- // from `main` so the workflow definition and the scripts match. Everything
- // else resolves to `dev`.
+ // that supplied the privileged workflow. Every pull_request event resolves
+ // to `dev`, the only integration branch.
//
- // Exact equality, not fragment matching: separate checks for `status`,
- // `main`, and `dev` would all pass with the operator grouping wrong or a
- // surviving `base.sha` fallback.
+ // Exact equality, not fragment matching: separate checks for `status` and
+ // `dev` would both pass with the operator grouping wrong or a surviving
+ // `base.sha` fallback.
const ref = checkoutStep.match(/^\s*ref:\s*(.+)$/m)?.[1];
assert.ok(ref, "trusted checkout must declare ref");
assert.equal(
ref.replace(/\s+/g, " ").trim(),
- "${{ github.event_name == 'status' && github.event.repository.default_branch || (github.event.pull_request.base.ref == 'main' && 'main' || 'dev') }}",
+ "${{ github.event_name == 'status' && github.event.repository.default_branch || 'dev' }}",
);
assert.doesNotMatch(ref, /base\.sha|head\.(?:sha|ref)/);
// Pinning the checkout ref only gates one step. A later `run:` or
@@ -215,7 +214,7 @@ describe("enforce-pr-target workflow", () => {
const checkouts = workflow.match(/uses:\s*actions\/checkout@[\s\S]*?(?=\n {6}- name:|$)/g) ?? [];
for (const step of checkouts) {
const stepRef = (step.match(/^\s*ref:\s*(.+)$/m)?.[1] ?? "").replace(/\s+/g, " ").trim();
- assert.equal(stepRef, "${{ github.event_name == 'status' && github.event.repository.default_branch || (github.event.pull_request.base.ref == 'main' && 'main' || 'dev') }}", "every checkout must use the trusted ref");
+ assert.equal(stepRef, "${{ github.event_name == 'status' && github.event.repository.default_branch || 'dev' }}", "every checkout must use the trusted ref");
assert.doesNotMatch(step, /repository:/, "a checkout must not retarget its repository");
}
// Checkout is not the only way to obtain PR-controlled code. A `run:` step
diff --git a/.github/scripts/pr-hygiene.test.cjs b/.github/scripts/pr-hygiene.test.cjs
index 64548f0b011..165d78566a2 100644
--- a/.github/scripts/pr-hygiene.test.cjs
+++ b/.github/scripts/pr-hygiene.test.cjs
@@ -314,7 +314,7 @@ describe("pr-hygiene workflow trust boundary", () => {
assert.ok(ref, "trusted checkout must declare ref");
assert.equal(
ref.replace(/\s+/g, " ").trim(),
- "${{ github.event.pull_request.base.ref == 'main' && 'main' || 'dev' }}",
+ "dev",
);
// A stacked child PR's base is another open PR's head; neither a base nor
// a head ref may select the code that runs with the write-capable token.
@@ -355,7 +355,7 @@ describe("pr-hygiene workflow trust boundary", () => {
const checkouts = workflow.match(/uses:\s*actions\/checkout@[\s\S]*?(?=\n {6}- name:|$)/g) ?? [];
for (const step of checkouts) {
const stepRef = (step.match(/^\s*ref:\s*(.+)$/m)?.[1] ?? "").replace(/\s+/g, " ").trim();
- assert.equal(stepRef, "${{ github.event.pull_request.base.ref == 'main' && 'main' || 'dev' }}", "every checkout must use the trusted ref");
+ assert.equal(stepRef, "dev", "every checkout must use the trusted ref");
assert.doesNotMatch(step, /repository:/, "a checkout must not retarget its repository");
}
// Checkout is not the only way to obtain PR-controlled code. A `run:` step
diff --git a/.github/scripts/pr-quality-messages.cjs b/.github/scripts/pr-quality-messages.cjs
index 56233036ebc..c37625ea516 100644
--- a/.github/scripts/pr-quality-messages.cjs
+++ b/.github/scripts/pr-quality-messages.cjs
@@ -274,17 +274,7 @@ function buildFailureSections(failures, { pr, allowedBases, defaultBase }) {
"",
`This pull request currently targets ${inlineCode(pr.base.ref)}, but pull requests must target one of ${allowedBases.map(inlineCode).join(" or ")}.`,
"",
- `@${pr.user.login} Please retarget this PR to ${inlineCode(defaultBase)}. All contributions go to ${inlineCode(defaultBase)}; \`main\` receives only release promotions. See our [Contributing guide](https://lidge-jun.github.io/opencodex/contributing/) for details. Thanks! 🙏`
- );
- }
-
- if (failures.some(failure => failure.code === "wrong_ancestry")) {
- sections.push(
- "⚠️ **Wrong branch ancestry**",
- "",
- `This pull request targets ${inlineCode(pr.base.ref)}, but its head appears to sit on the current ${inlineCode("main")} tip while being far behind ${inlineCode(pr.base.ref)}.`,
- "",
- `@${pr.user.login} Rebase onto the current ${inlineCode(pr.base.ref)} branch instead of opening from ${inlineCode("main")}. That keeps already-released commits out of the integration branch.`
+ `@${pr.user.login} Please retarget this PR to ${inlineCode(defaultBase)}. All contributions go to ${inlineCode(defaultBase)}. See our [Contributing guide](https://lidge-jun.github.io/opencodex/contributing/) for details. Thanks! 🙏`
);
}
@@ -322,9 +312,6 @@ function failureSummary(failures, { pr }) {
if (failure.code === "wrong_base") {
return `wrong base (${pr.base.ref})`;
}
- if (failure.code === "wrong_ancestry") {
- return "wrong ancestry";
- }
if (failure.code === "bad_description") {
return `bad description (${failure.reason})`;
}
diff --git a/.github/scripts/pr-quality-messages.test.cjs b/.github/scripts/pr-quality-messages.test.cjs
index f4665ae0d6a..ad209ccc325 100644
--- a/.github/scripts/pr-quality-messages.test.cjs
+++ b/.github/scripts/pr-quality-messages.test.cjs
@@ -143,19 +143,17 @@ describe("buildFailureSections", () => {
assert.match(sections, /@contributor Please retarget this PR to `dev`/);
});
- it("builds ancestry, description, and screenshot sections", () => {
+ it("builds description and screenshot sections", () => {
const sections = buildFailureSections(
[
- { code: "wrong_ancestry" },
{ code: "bad_description", reason: "empty" },
{ code: "missing_ui_screenshot" }
],
{ pr: PR, allowedBases: ALLOWED_BASES, defaultBase: DEFAULT_BASE },
).join("\n");
- assert.match(sections, /Wrong branch ancestry/);
assert.match(sections, /Pull request description/);
assert.match(sections, /UI screenshot required/);
- assert.match(sections, /Rebase onto the current `main`/);
+ assert.doesNotMatch(sections, /Wrong branch ancestry/);
});
});
@@ -165,14 +163,13 @@ describe("failureSummary", () => {
failureSummary(
[
{ code: "wrong_base" },
- { code: "wrong_ancestry" },
{ code: "bad_description", reason: "empty" },
{ code: "missing_ui_screenshot" },
{ code: "mystery" }
],
{ pr: PR },
),
- "wrong base (main); wrong ancestry; bad description (empty); missing UI screenshot; mystery",
+ "wrong base (main); bad description (empty); missing UI screenshot; mystery",
);
});
});
diff --git a/.github/scripts/pr-quality.cjs b/.github/scripts/pr-quality.cjs
index ddee9226bb6..edc95afbd8f 100644
--- a/.github/scripts/pr-quality.cjs
+++ b/.github/scripts/pr-quality.cjs
@@ -12,9 +12,6 @@ const { READINESS_LATEST_DEV_BEHIND_MAX } = require(
path.join(__dirname, "pr-quality-state.cjs")
);
-const ANCESTRY_BEHIND_THRESHOLD = 20;
-/** Cap on ahead_by vs main so stale `dev` forks (many commits ahead of main) are not flagged. */
-const ANCESTRY_AHEAD_MAIN_MAX = 5;
const MIN_SECTION_LEN = 40;
const MIN_RICH_SECTIONS = 2;
const UNSTRUCTURED_MIN_LEN = 120;
@@ -106,20 +103,6 @@ const MARKDOWN_REFERENCE_DEF_RE = /^\s*\[([^\]]+)\]:\s*\S+/gm;
/** Embedded HTML image with a renderable `src` (`
`). */
const HTML_IMAGE_RE = /
]*\bsrc\s*=\s*(?:"[^"]+"|'[^']+'|[^\s>"']+)[^>]*>/i;
-function isWrongAncestry({
- behindMain,
- behindBase,
- aheadMain = 0,
- threshold = ANCESTRY_BEHIND_THRESHOLD,
- aheadMainMax = ANCESTRY_AHEAD_MAIN_MAX,
-}) {
- return (
- behindMain === 0 &&
- behindBase >= threshold &&
- aheadMain <= aheadMainMax
- );
-}
-
function authorHasPushPermission(permission) {
return permission === "admin" || permission === "maintain" || permission === "write";
}
@@ -528,12 +511,6 @@ function collectPrQualityFailures({
allowedBases,
title = "",
body,
- behindMain,
- behindBase,
- aheadMain = 0,
- authorPermission,
- permissionLookupFailed = false,
- ancestryLookupFailed = false,
/** True when baseRef is another open PR's head (stacked child). */
stackedBase = false,
/** Issue comments; a maintainer comment waives the GUI-screenshot gate. */
@@ -550,21 +527,6 @@ function collectPrQualityFailures({
const wrongBase = !allowedBases.includes(baseRef) && !stackedBase;
if (wrongBase) {
failures.push({ code: "wrong_base" });
- } else {
- // Permission lookup fails closed (still evaluate ancestry). Compare API
- // failures skip ancestry — zeros would falsely pass the #644 heuristic.
- // Stacked children skip ancestry against the integration base; their parent
- // PR is the temporary target.
- const skipAncestry =
- stackedBase ||
- ancestryLookupFailed ||
- (!permissionLookupFailed && authorHasPushPermission(authorPermission));
- if (
- !skipAncestry &&
- isWrongAncestry({ behindMain, behindBase, aheadMain })
- ) {
- failures.push({ code: "wrong_ancestry" });
- }
}
const desc = assessPrDescription(body);
@@ -587,12 +549,9 @@ function collectPrQualityFailures({
}
module.exports = {
- ANCESTRY_BEHIND_THRESHOLD,
- ANCESTRY_AHEAD_MAIN_MAX,
REVIEW_READINESS_ITEMS,
REVIEW_READINESS_START,
REVIEW_READINESS_END,
- isWrongAncestry,
authorHasPushPermission,
assessPrDescription,
guiPathsChanged,
diff --git a/.github/scripts/pr-quality.test.cjs b/.github/scripts/pr-quality.test.cjs
index 996e5b08676..b4287bfeb0f 100644
--- a/.github/scripts/pr-quality.test.cjs
+++ b/.github/scripts/pr-quality.test.cjs
@@ -3,9 +3,7 @@
const { describe, it } = require("node:test");
const assert = require("node:assert/strict");
const {
- ANCESTRY_BEHIND_THRESHOLD,
REVIEW_READINESS_ITEMS,
- isWrongAncestry,
authorHasPushPermission,
assessPrDescription,
hasGuiCue,
@@ -25,32 +23,6 @@ const {
collectPrQualityFailures,
} = require("./pr-quality.cjs");
-describe("isWrongAncestry", () => {
- it("flags #644-shaped compares (0 behind main, far behind base, few ahead of main)", () => {
- assert.equal(
- isWrongAncestry({ behindMain: 0, behindBase: 44, aheadMain: 1 }),
- true,
- );
- });
-
- it("uses threshold 20 by default", () => {
- assert.equal(ANCESTRY_BEHIND_THRESHOLD, 20);
- assert.equal(isWrongAncestry({ behindMain: 0, behindBase: 20, aheadMain: 1 }), true);
- assert.equal(isWrongAncestry({ behindMain: 0, behindBase: 19, aheadMain: 1 }), false);
- });
-
- it("passes when head is behind main (not sitting on main tip)", () => {
- assert.equal(isWrongAncestry({ behindMain: 1, behindBase: 44, aheadMain: 1 }), false);
- });
-
- it("passes stale dev-based branches that are many commits ahead of main", () => {
- assert.equal(
- isWrongAncestry({ behindMain: 0, behindBase: 44, aheadMain: 50 }),
- false,
- );
- });
-});
-
describe("authorHasPushPermission", () => {
it("accepts write/maintain/admin only", () => {
assert.equal(authorHasPushPermission("admin"), true);
@@ -680,12 +652,8 @@ describe("collectPrQualityFailures", () => {
baseRef: "main",
allowedBases: allowed,
body: "## Summary\n" + "x".repeat(50) + "\n\n## Test plan\n" + "y".repeat(50),
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
});
assert.ok(failures.some((f) => f.code === "wrong_base"));
- assert.ok(!failures.some((f) => f.code === "wrong_ancestry"));
});
it("reports wrong_base and bad_description together for main + empty body", () => {
@@ -693,16 +661,16 @@ describe("collectPrQualityFailures", () => {
baseRef: "main",
allowedBases: allowed,
body: "",
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
});
assert.ok(failures.some((f) => f.code === "wrong_base"));
assert.ok(failures.some((f) => f.code === "bad_description"));
- assert.ok(!failures.some((f) => f.code === "wrong_ancestry"));
});
- it("reports wrong_ancestry for contributor on #644-shaped compare", () => {
+ it("no longer fails a contributor for sitting on the deleted main tip", () => {
+ // The old `main...head` heuristic flagged a head that was level with
+ // `main` but far behind `dev`. `main` no longer exists, so there is no tip
+ // to compare against and no ancestry failure to raise. Being far behind
+ // `dev` is handled by the review-readiness latest-dev claim instead.
const failures = collectPrQualityFailures({
baseRef: "dev",
allowedBases: allowed,
@@ -714,91 +682,17 @@ describe("collectPrQualityFailures", () => {
"- Launch the tray app after setting CODEX_HOME",
"- Confirm the listener and launcher use the same workspace root",
].join("\n"),
- behindMain: 0,
- behindBase: 44,
- aheadMain: 1,
- authorPermission: "read",
});
- assert.deepEqual(
- failures.map((f) => f.code),
- ["wrong_ancestry"],
- );
+ assert.deepEqual(failures, []);
});
- it("skips ancestry for push permission but still flags bad description", () => {
+ it("still flags a bad description for a contributor head", () => {
const failures = collectPrQualityFailures({
baseRef: "dev",
allowedBases: allowed,
body: "",
- behindMain: 0,
- behindBase: 44,
- aheadMain: 1,
- authorPermission: "write",
- });
- assert.ok(!failures.some((f) => f.code === "wrong_ancestry"));
- assert.ok(failures.some((f) => f.code === "bad_description"));
- });
-
- it("applies ancestry when permission lookup failed (fail closed)", () => {
- const failures = collectPrQualityFailures({
- baseRef: "dev",
- allowedBases: allowed,
- body: [
- "## Summary",
- "This change updates the Windows tray launcher so it resolves CODEX_HOME through the shared helper instead of a hardcoded path.",
- "",
- "## Test plan",
- "- Launch the tray app after setting CODEX_HOME",
- "- Confirm the listener and launcher use the same workspace root",
- ].join("\n"),
- behindMain: 0,
- behindBase: 44,
- aheadMain: 1,
- authorPermission: null,
- permissionLookupFailed: true,
- });
- assert.ok(failures.some((f) => f.code === "wrong_ancestry"));
- });
-
- it("does not flag stale dev-based branches that are far ahead of main", () => {
- const failures = collectPrQualityFailures({
- baseRef: "dev",
- allowedBases: allowed,
- body: [
- "## Summary",
- "This change updates the Windows tray launcher so it resolves CODEX_HOME through the shared helper instead of a hardcoded path.",
- "",
- "## Test plan",
- "- Launch the tray app after setting CODEX_HOME",
- "- Confirm the listener and launcher use the same workspace root",
- ].join("\n"),
- behindMain: 0,
- behindBase: 44,
- aheadMain: 50,
- authorPermission: "read",
- });
- assert.ok(!failures.some((f) => f.code === "wrong_ancestry"));
- });
-
- it("skips ancestry when compare lookup failed (cannot evaluate)", () => {
- const failures = collectPrQualityFailures({
- baseRef: "dev",
- allowedBases: allowed,
- body: [
- "## Summary",
- "This change updates the Windows tray launcher so it resolves CODEX_HOME through the shared helper instead of a hardcoded path.",
- "",
- "## Test plan",
- "- Launch the tray app after setting CODEX_HOME",
- "- Confirm the listener and launcher use the same workspace root",
- ].join("\n"),
- behindMain: 0,
- behindBase: 0,
- aheadMain: 0,
- authorPermission: "read",
- ancestryLookupFailed: true,
});
- assert.ok(!failures.some((f) => f.code === "wrong_ancestry"));
+ assert.deepEqual(failures.map((f) => f.code), ["bad_description"]);
});
it("skips wrong_base when stackedBase is set", () => {
@@ -813,14 +707,9 @@ describe("collectPrQualityFailures", () => {
"- Launch the tray app after setting CODEX_HOME",
"- Confirm the listener and launcher use the same workspace root",
].join("\n"),
- behindMain: 0,
- behindBase: 44,
- aheadMain: 1,
- authorPermission: "read",
stackedBase: true,
});
assert.ok(!failures.some((f) => f.code === "wrong_base"));
- assert.ok(!failures.some((f) => f.code === "wrong_ancestry"));
});
it("still flags wrong_base for non-allow-list bases without stackedBase", () => {
@@ -828,9 +717,6 @@ describe("collectPrQualityFailures", () => {
baseRef: "main",
allowedBases: allowed,
body: "fix stuff",
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
stackedBase: false,
});
assert.ok(failures.some((f) => f.code === "wrong_base"));
@@ -842,9 +728,6 @@ describe("collectPrQualityFailures", () => {
allowedBases: allowed,
title: "Fix dashboard spacing",
body: richBody,
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: ["gui/src/App.tsx"],
});
assert.ok(failures.some((f) => f.code === "missing_ui_screenshot"));
@@ -856,9 +739,6 @@ describe("collectPrQualityFailures", () => {
allowedBases: allowed,
title: "GUI: fix provider list spacing",
body: richBody,
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: ["scripts/foo.ts"],
});
assert.ok(!failures.some((f) => f.code === "missing_ui_screenshot"));
@@ -871,9 +751,6 @@ describe("collectPrQualityFailures", () => {
allowedBases: allowed,
title: "Large refactor",
body: richBody,
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: truncatedPaths,
filesTruncated: true,
});
@@ -888,9 +765,6 @@ describe("collectPrQualityFailures", () => {
allowedBases: allowed,
title: "Large refactor with gui tweak",
body: richBody,
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: truncatedPaths,
filesTruncated: true,
});
@@ -909,9 +783,6 @@ describe("collectPrQualityFailures", () => {
"## Test plan",
"- Ran bun test tests/ci-workflows/ci-workflows.test.ts",
].join("\n"),
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: ["scripts/foo.ts"],
});
assert.ok(!failures.some((f) => f.code === "missing_ui_screenshot"));
@@ -929,9 +800,6 @@ describe("collectPrQualityFailures", () => {
"## Test plan",
"- Ran bun test tests/ci-workflows/ci-workflows.test.ts",
].join("\n"),
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: ["gui/src/styles.css"],
});
assert.ok(failures.some((f) => f.code === "missing_ui_screenshot"));
@@ -949,9 +817,6 @@ describe("collectPrQualityFailures", () => {
"## Test plan",
"- Ran bun test tests/ci-workflows/ci-workflows.test.ts",
].join("\n"),
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: ["gui/src/App.tsx"],
guiOverrideComments: [
{ author_association: "OWNER", body: "no gui changes here" },
@@ -972,9 +837,6 @@ describe("collectPrQualityFailures", () => {
"## Test plan",
"- Ran bun test tests/ci-workflows/ci-workflows.test.ts",
].join("\n"),
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: ["gui/src/App.tsx"],
guiOverrideComments: [
{ author_association: "CONTRIBUTOR", body: "no gui changes here" },
@@ -997,9 +859,6 @@ describe("collectPrQualityFailures", () => {
"## Test plan",
"- Ran bun test tests/ci-workflows/ci-workflows.test.ts",
].join("\n"),
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: ["gui/src/App.tsx"],
});
assert.ok(!failures.some((f) => f.code === "missing_ui_screenshot"));
@@ -1021,9 +880,6 @@ describe("collectPrQualityFailures", () => {
"## Test plan",
"- Ran bun test tests/ci-workflows/ci-workflows.test.ts",
].join("\n"),
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: ["gui/src/App.tsx"],
});
assert.ok(!failures.some((f) => f.code === "missing_ui_screenshot"));
@@ -1045,9 +901,6 @@ describe("collectPrQualityFailures", () => {
"## Test plan",
"- Ran bun test tests/ci-workflows/ci-workflows.test.ts",
].join("\n"),
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
changedFilePaths: ["gui/src/App.tsx"],
});
assert.ok(failures.some((f) => f.code === "missing_ui_screenshot"));
@@ -1071,9 +924,6 @@ describe("collectPrQualityFailures", () => {
"- [ ] Docs or release notes were updated when needed.",
"- [ ] Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.",
].join("\n"),
- behindMain: 0,
- behindBase: 0,
- authorPermission: "read",
});
assert.ok(!failures.some((f) => f.code === "missing_ui_screenshot"));
});
diff --git a/.github/scripts/release-evidence-policy.json b/.github/scripts/release-evidence-policy.json
index 8e7b172027b..e82ef837c5d 100644
--- a/.github/scripts/release-evidence-policy.json
+++ b/.github/scripts/release-evidence-policy.json
@@ -166,5 +166,45 @@
"desktop/scripts/appimage-patchelf.py": "63e78ef74160bc48fbcdd882065f1d416db6d13c",
"desktop/scripts/linux-packaged-e2e.ts": "9ca92352668ff881c85caea44a9b4747bedc7e2d"
}
+ },
+ {
+ "kind": "ci",
+ "version": 1,
+ "files": {
+ ".github/workflows/ci.yml": "dc5496ad7e6a146a94fbe8dfeaa3b73461feafbc",
+ ".github/actions/setup-project-bun/action.yml": "cf28f6f9d4385d69784f4e3610914f6952ce789d",
+ ".github/scripts/release-evidence.cjs": "c4cd8c762abbfc1c0674937535c5a36b9cf705fd",
+ ".github/scripts/release-evidence.test.cjs": "de30ad37105cf0e7dd8c538efb5ee1cfafe02990",
+ "scripts/ci/select-test-lane.sh": "b25836cb55f962d1ffd9e68ed00f45f8b45becc8",
+ "scripts/ci/windows-sensitive-diff.sh": "03495f256c671aff57e750febffe19ca7face6a1",
+ "scripts/ci/run-bun-test-batches.sh": "f8aa18e80aff1c95c584cd2c879dfbb6806c11fb",
+ "scripts/ci/bun-crash-signatures.sh": "d34662ddd07864d97bed909135095db33fe42c9e",
+ "scripts/ci/bun-install-frozen.sh": "e6d7bc3aec044e12297c7c4c04015a33df0eb22b",
+ "scripts/ci/docker-smoke.ts": "a8424f93986a31625a0a236cdab5667db67b3405",
+ "scripts/ci/test-durations.tsv": "0c7b8eeac35a5f09414d1b77185733b5936c594f",
+ "scripts/ci/test-durations.windows.tsv": "5ee31b6bd6cada6ab7d806ea03dd0d8e46fe1d29",
+ "scripts/test.ts": "363bf072c4b689478fdbb76a61bf4eadbc054548",
+ "scripts/lib/test-runner-bun.ts": "8763806104a851dbdefeea8cffe8d7dd8d1c8da1",
+ "scripts/test-temp-lock.ts": "ee83fb254b728de119028f52b9894bf52d7aea15",
+ "scripts/ci/run-changed-tests.sh": "9a54d3a5db9849bcbe0dd766954a840185419fa5",
+ "scripts/keyring-smoke.ts": "cd3be07ad57796172696dfa053ea1fb129f29365",
+ "scripts/privacy-scan.ts": "86314e891b45e49739b94c76cddd9e4cc2d4340f",
+ "scripts/structure-ssot.ts": "40ba68401df9b77156afed66d6a11c61df8e9a41",
+ "scripts/generate-ocx-skill-surface.ts": "750ea21e5668aa512a83aa5a7f8cd7bc5cbd79db",
+ "desktop/scripts/prepare-sidecar.ts": "20f7eec61f73635ea681e25f13dd850b62bb41e2",
+ "desktop/scripts/build-widget.sh": "38e0eb9d713804b603aa75c32383aa18ef01d06c",
+ "desktop/scripts/verify-macos-runtime.sh": "43f1a31375c6f6fe7dcafb9d96c231b98d1f6ba4",
+ "desktop/scripts/verify-linux-sidecar.sh": "c502bb5c8ba8346c722a8f5274f2274bb325a934",
+ "desktop/scripts/appimage-patchelf.py": "63e78ef74160bc48fbcdd882065f1d416db6d13c",
+ "desktop/scripts/linux-packaged-e2e.ts": "9ca92352668ff881c85caea44a9b4747bedc7e2d"
+ }
+ },
+ {
+ "kind": "service",
+ "version": 1,
+ "files": {
+ ".github/workflows/service-lifecycle.yml": "87249bf4d19ce47a6eafa59703fd8e52453cc924",
+ ".github/actions/setup-project-bun/action.yml": "cf28f6f9d4385d69784f4e3610914f6952ce789d"
+ }
}
]
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4d1d82f1d26..dc5496ad7e6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,7 +15,7 @@ on:
# docs-only PR receives explicit positive evidence instead of no check at all.
pull_request: {}
# No base-branch filter on purpose. GitHub matches `branches:` against the
- # BASE ref, so `[main, dev]` silently excluded stacked child PRs — whose
+ # BASE ref, so even `[dev]` would silently exclude stacked child PRs — whose
# base is another open PR's head branch, an intentional review workflow per
# AGENTS.md that `enforce-target` already exempts from the wrong-base gate.
# The #951-#955 stack merged with `enforce-target`, `label`, and
@@ -225,14 +225,15 @@ jobs:
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with:
# Without this the action compares against the repository's DEFAULT
- # branch, which is `main`. A push to `dev` would then be diffed against
- # `main`, so every area touched since the last promotion keeps reading
- # as "changed" — the scoped jobs would run on nearly every dev push and
- # the saving would silently not happen while CI stayed green.
+ # branch, which is `dev`. For a non-PR event that diff starts at
+ # `dev` itself, so every area touched since the branch point keeps
+ # reading as "changed" — the scoped jobs would run on nearly every
+ # such event and the saving would silently not happen while CI stayed
+ # green.
#
# On `pull_request` the action ignores this and uses the PR's own file
- # list. On a branch push it means "compare against the previous commit
- # on this branch", which is the intent.
+ # list. Otherwise `github.ref` keeps the diff scoped to this ref, which
+ # is the intent.
base: ${{ github.ref }}
filters: |
# Pull requests always
@@ -305,11 +306,11 @@ jobs:
- '.github/workflows/ci.yml'
# The docs site is built by nothing else on a pull request. `ci` above
# deliberately omits `docs-site/**` -- a prose edit has no business
- # starting the cross-platform suite -- and `deploy-docs.yml` triggers
- # only on `push` to `main`. That left the Astro toolchain with no
- # pull-request build gate at all, so a dependency bump under
- # `docs-site/` could only be proven by an author's local run and would
- # otherwise surface at promotion.
+ # starting the cross-platform suite -- and `deploy-docs.yml` is
+ # dispatch-only. That left the Astro toolchain with no pull-request
+ # build gate at all, so a dependency bump under `docs-site/` could
+ # only be proven by an author's local run and would otherwise surface
+ # at release time.
#
# `.github/workflows/ci.yml` is here so an edit to the job below
# verifies itself. Without it this filter's own pull request would
@@ -565,9 +566,10 @@ jobs:
PATH_SELECTED: ${{ steps.filter.outputs.windows }}
run: bash scripts/ci/windows-sensitive-diff.sh
- # A scheduled run starts from main's head. Resolve dev ONCE so the nine
- # Windows shards, the macOS control and every other job test one commit,
- # however long the queue between them. contents: read already covers it.
+ # A scheduled run starts from the default branch's head, which is `dev`.
+ # Resolve dev ONCE so the nine Windows shards, the macOS control and every
+ # other job test one commit, however long the queue between them.
+ # contents: read already covers it.
- name: Resolve the commit a scheduled run tests
id: nightly
shell: bash
@@ -1259,7 +1261,7 @@ jobs:
run: bun scripts/ci/docker-smoke.ts
# Proves the Astro toolchain still builds the site, on the only event that can
- # prove it before promotion.
+ # prove it before release.
#
# Linux only, and one leg. The site is static output from a Node/Bun toolchain
# with no OS-specific behaviour to promise, so a Windows or macOS leg would buy
diff --git a/.github/workflows/cleanup-closed-pr-branches.yml b/.github/workflows/cleanup-closed-pr-branches.yml
index 4b0c1229a9f..8cbca5076b9 100644
--- a/.github/workflows/cleanup-closed-pr-branches.yml
+++ b/.github/workflows/cleanup-closed-pr-branches.yml
@@ -5,9 +5,8 @@ name: Clean branches from closed pull requests
# merging leaves its head branch behind forever, which is how this repository
# accumulated dozens of dead `codex/*` and `ingw/*` branches.
#
-# Scheduled workflows only run from the repository DEFAULT branch (currently
-# `main`), not from `dev`. Landing this on `dev` alone does not start the
-# cleanup until the change is also promoted to that default branch.
+# Scheduled workflows only run from the repository DEFAULT branch, which is
+# `dev`. A change lands on the live cleanup as soon as it is on `dev`.
on:
schedule:
# Daily at 06:30 UTC (offset from the hour to reduce Action load spikes).
diff --git a/.github/workflows/cleanup-orphaned-workflows.yml b/.github/workflows/cleanup-orphaned-workflows.yml
index f0360fb92eb..02d7005cd99 100644
--- a/.github/workflows/cleanup-orphaned-workflows.yml
+++ b/.github/workflows/cleanup-orphaned-workflows.yml
@@ -7,13 +7,6 @@ on:
schedule:
# Daily at 06:00 UTC.
- cron: "0 6 * * *"
- push:
- branches: [main]
- paths:
- # The first promotion to main performs the initial backlog cleanup without
- # exposing a branch-selectable manual trigger with actions:write.
- - ".github/workflows/cleanup-orphaned-workflows.yml"
- - "scripts/ci/cleanup-orphaned-workflows.mjs"
permissions:
actions: write # Required to delete orphaned workflow runs through the Actions API.
diff --git a/.github/workflows/codex-queue-helpers.yml b/.github/workflows/codex-queue-helpers.yml
index 62b5991b793..7145a1fa1a9 100644
--- a/.github/workflows/codex-queue-helpers.yml
+++ b/.github/workflows/codex-queue-helpers.yml
@@ -7,14 +7,6 @@ on:
- 'docs-site/astro.config.mjs'
- 'docs-site/src/content/docs/guides/composer-usage-gate-fallback.md'
- '.github/workflows/codex-queue-helpers.yml'
- push:
- branches: [main, preview]
- paths:
- - 'scripts/codex-queue.*'
- - 'docs-site/astro.config.mjs'
- - 'docs-site/src/content/docs/guides/composer-usage-gate-fallback.md'
- - '.github/workflows/codex-queue-helpers.yml'
-
workflow_dispatch:
permissions:
diff --git a/.github/workflows/dev-version-bump.yml b/.github/workflows/dev-version-bump.yml
index 99a8946c3e4..cd99285c430 100644
--- a/.github/workflows/dev-version-bump.yml
+++ b/.github/workflows/dev-version-bump.yml
@@ -19,8 +19,8 @@ name: Dev version bump
#
# A branch-selected dispatch executes that branch's workflow body with write permission.
# The in-job guard therefore rejects accidental non-default-ref dispatches. It is an early
-# warning, not a security boundary: a writer could remove it on their branch. Protected
-# release branches and the required review on `dev` remain the enforcement boundaries.
+# warning, not a security boundary: a writer could remove it on their branch. The protected
+# `dev` branch and its required review remain the enforcement boundaries.
on:
workflow_dispatch:
inputs:
diff --git a/.github/workflows/enforce-issue-quality.yml b/.github/workflows/enforce-issue-quality.yml
index a983da5d781..1531fb79f8b 100644
--- a/.github/workflows/enforce-issue-quality.yml
+++ b/.github/workflows/enforce-issue-quality.yml
@@ -1,9 +1,8 @@
name: Enforce issue quality
-# Issue events always load this workflow from the repository DEFAULT branch
-# (currently `main`), not from `dev`. Landing here on `dev` alone does not
-# change live issue-quality behavior until the change is also on that default
-# branch.
+# Issue events always load this workflow from the repository DEFAULT branch,
+# which is `dev`. A change lands on the live issue-quality gate as soon as it is
+# on `dev`.
on:
issues:
types:
diff --git a/.github/workflows/enforce-pr-target.yml b/.github/workflows/enforce-pr-target.yml
index dfcb50cc809..d2a9674595b 100644
--- a/.github/workflows/enforce-pr-target.yml
+++ b/.github/workflows/enforce-pr-target.yml
@@ -191,19 +191,17 @@ jobs:
# PR's head, so `base.sha` let an unpromoted commit choose which code
# runs with this job's contents/pull-requests write token.
#
- # The branch is chosen, not fixed. `status` has no pull_request
- # payload and runs the privileged workflow from the repository
- # default branch, so it sources from that same promoted boundary. A
- # `main`-targeting PR must take its scripts from `main`, or the gate
- # runs a `main` workflow definition against `dev` scripts. Every
- # other base, including a stacked child's, resolves to `dev`.
- ref: ${{ github.event_name == 'status' && github.event.repository.default_branch || (github.event.pull_request.base.ref == 'main' && 'main' || 'dev') }}
+ # `status` has no pull_request payload and runs the privileged
+ # workflow from the repository default branch, so it sources from
+ # that same boundary. Every pull_request event, including a stacked
+ # child's, resolves to `dev`, the single integration branch.
+ ref: ${{ github.event_name == 'status' && github.event.repository.default_branch || 'dev' }}
persist-credentials: false
sparse-checkout: |
.github/scripts
MAINTAINERS.md
- - name: Enforce PR target, ancestry, and description
+ - name: Enforce PR target and description
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
env:
RESOLVED_PULL_NUMBER: ${{ needs.resolve-pr.outputs.pull-number }}
@@ -683,9 +681,7 @@ jobs:
gateState.pendingReattestation = null;
}
- let behindMain = 0;
let behindBase = 0;
- let aheadMain = 0;
let ancestryLookupFailed = false;
const baseAllowed = ALLOWED_BASES.includes(pr.base.ref);
@@ -725,15 +721,10 @@ jobs:
if (baseAllowed) {
const headSha = pr.head.sha;
try {
- const { data: mainCompare } =
- await github.rest.repos.compareCommitsWithBasehead({
- owner,
- repo,
- basehead: `main...${headSha}`
- });
- behindMain = mainCompare.behind_by;
- aheadMain = mainCompare.ahead_by;
-
+ // `dev` is the only integration branch now. This single
+ // compare feeds the review-readiness latest-dev claim; there
+ // is no deleted `main` tip to compare against, so no
+ // wrong-ancestry verdict is derived here.
const { data: baseCompare } =
await github.rest.repos.compareCommitsWithBasehead({
owner,
@@ -805,12 +796,6 @@ jobs:
allowedBases: ALLOWED_BASES,
title: pr.title,
body: pr.body,
- behindMain,
- behindBase,
- aheadMain,
- authorPermission,
- permissionLookupFailed,
- ancestryLookupFailed,
stackedBase,
// A maintainer issue comment ("not touching gui") waives the
// GUI-screenshot gate; the comments are already fetched above.
@@ -1263,11 +1248,6 @@ jobs:
`Retarget this PR to ${inlineCode(DEFAULT_BASE)} — all contributions go to ${inlineCode(DEFAULT_BASE)}.`
);
}
- if (failures.some(failure => failure.code === "wrong_ancestry")) {
- actions.push(
- `Rebase onto the current ${inlineCode(DEFAULT_BASE)} branch instead of opening from ${inlineCode("main")}.`
- );
- }
if (failures.some(failure => failure.code === "bad_description")) {
actions.push(
"Add a real **Summary** and **Test plan** to the PR description."
@@ -1396,9 +1376,6 @@ jobs:
if (failure.code === "wrong_base") {
return `wrong target branch (${pr.base.ref}); retarget to ${inlineCode(DEFAULT_BASE)}.`;
}
- if (failure.code === "wrong_ancestry") {
- return "wrong branch ancestry; rebase onto the latest dev.";
- }
if (failure.code === "bad_description") {
return `PR description needs work (${failure.reason}).`;
}
diff --git a/.github/workflows/issue-quality-tests.yml b/.github/workflows/issue-quality-tests.yml
index fd064ce1013..3917fda15df 100644
--- a/.github/workflows/issue-quality-tests.yml
+++ b/.github/workflows/issue-quality-tests.yml
@@ -35,42 +35,6 @@ on:
- ".github/workflows/issue-triage.yml"
- ".github/workflows/issue-quality-tests.yml"
- ".github/workflows/pr-hygiene.yml"
- push:
- # Release lines only; review is covered by the pull_request trigger above.
- branches: [main, preview]
- paths:
- - ".github/ISSUE_TEMPLATE/**"
- - ".github/scripts/issue-quality.cjs"
- - ".github/scripts/issue-quality-core.cjs"
- - ".github/scripts/issue-quality*.test.cjs"
- - ".github/scripts/pr-quality.cjs"
- - ".github/scripts/pr-quality.test.cjs"
- - ".github/scripts/pr-quality-messages.cjs"
- - ".github/scripts/pr-quality-messages.test.cjs"
- - ".github/scripts/pr-quality-state.cjs"
- - ".github/scripts/pr-readiness-reattest.cjs"
- - ".github/scripts/pr-quality-state.test.cjs"
- - ".github/scripts/pr-labeler.cjs"
- - ".github/scripts/pr-labeler.test.cjs"
- - ".github/scripts/enforce-pr-target.test.cjs"
- - ".github/scripts/pr-hygiene.cjs"
- - ".github/scripts/pr-hygiene.test.cjs"
- - ".github/scripts/pr-sponsored-surface.cjs"
- - ".github/scripts/pr-sponsored-surface.test.cjs"
- - ".github/scripts/issue-translation.cjs"
- - ".github/scripts/issue-translation.test.cjs"
- - ".github/scripts/issue-triage*.cjs"
- - ".github/scripts/copilot-workflows.test.cjs"
- - ".github/scripts/install-copilot-cli.sh"
- - ".github/scripts/run-copilot-inference*.cjs"
- - ".github/scripts/parse-issue-translation-response.cjs"
- - ".github/scripts/parse-issue-translation-response.test.cjs"
- - ".github/workflows/enforce-issue-quality.yml"
- - ".github/workflows/enforce-pr-target.yml"
- - ".github/workflows/pr-labeler.yml"
- - ".github/workflows/issue-triage.yml"
- - ".github/workflows/issue-quality-tests.yml"
- - ".github/workflows/pr-hygiene.yml"
permissions:
contents: read
diff --git a/.github/workflows/pr-hygiene.yml b/.github/workflows/pr-hygiene.yml
index 74be06069f9..73e7bb72bfe 100644
--- a/.github/workflows/pr-hygiene.yml
+++ b/.github/workflows/pr-hygiene.yml
@@ -41,12 +41,11 @@ jobs:
# PR's head, so `base.sha` let an unpromoted commit choose which code
# runs with this job's issues/pull-requests write token.
#
- # The branch is chosen, not fixed: `pull_request_target` loads this
- # workflow from the default branch, so a `main`-targeting PR must
- # take its scripts from `main` too, or the gate runs a `main`
- # workflow against `dev` scripts. Everything else, including stacked
- # bases, resolves to `dev`, the single integration line.
- ref: ${{ github.event.pull_request.base.ref == 'main' && 'main' || 'dev' }}
+ # `pull_request_target` loads this workflow from the default branch,
+ # and `dev` is the single integration line. A fixed `dev` keeps the
+ # scripts, workflow definition, and stacked children on one trusted
+ # revision.
+ ref: dev
persist-credentials: false
sparse-checkout: .github/scripts
diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml
index 309fd40b8f1..f7c2b6fa63e 100644
--- a/.github/workflows/pr-labeler.yml
+++ b/.github/workflows/pr-labeler.yml
@@ -1,9 +1,8 @@
name: PR Labeler
# pull_request_target always loads this workflow from the repository DEFAULT
-# branch (currently `main`), not from `dev`. Landing here on `dev` alone does
-# not change live labeler behavior until the change is also on that default
-# branch — same promotion model as enforce-issue-quality.yml.
+# branch, which is `dev`. A change lands on the live labeler as soon as it is on
+# `dev` — same model as enforce-issue-quality.yml.
on:
pull_request_target:
# labeled/unlabeled let a human type-label change enqueue a fresher run in the
diff --git a/.github/workflows/react-doctor.yml b/.github/workflows/react-doctor.yml
index 93d8a38e3df..2efa81541c8 100644
--- a/.github/workflows/react-doctor.yml
+++ b/.github/workflows/react-doctor.yml
@@ -23,9 +23,6 @@ on:
paths:
- "gui/**"
- ".github/workflows/react-doctor.yml"
- # Scans `main` on every push to track the health-score trend.
- push:
- branches: ["main"]
permissions:
contents: read
@@ -34,8 +31,8 @@ permissions:
# and the CLI exits 1 on ENOENT even for fork PRs.
pull-requests: read
-# Cancels any in-flight scan for the same PR (or branch, on push) the moment a
-# new commit arrives, so only the latest run remains.
+# Cancels any in-flight scan for the same PR the moment a new commit arrives,
+# so only the latest run remains.
concurrency:
group: react-doctor-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
diff --git a/.github/workflows/service-lifecycle.yml b/.github/workflows/service-lifecycle.yml
index 496319bee65..87249bf4d19 100644
--- a/.github/workflows/service-lifecycle.yml
+++ b/.github/workflows/service-lifecycle.yml
@@ -2,7 +2,7 @@ name: Service lifecycle
on:
pull_request:
- branches: [main, dev]
+ branches: [dev]
paths:
- "src/service.ts"
# The service implementation is the src/service/ directory; src/service.ts is only
diff --git a/.github/workflows/stale-needs-info.yml b/.github/workflows/stale-needs-info.yml
index d33fb204a51..ca9838ff21b 100644
--- a/.github/workflows/stale-needs-info.yml
+++ b/.github/workflows/stale-needs-info.yml
@@ -1,16 +1,14 @@
name: Close stale needs-info issues
-# Scheduled workflows only run from the repository DEFAULT branch
-# (currently `main`), not from `dev`. Landing here on `dev` alone does not
-# change live issue-stale behavior until the change is also on that default
-# branch.
+# Scheduled workflows only run from the repository DEFAULT branch, which is
+# `dev`. A change lands on the live schedule as soon as it is on `dev`.
on:
schedule:
# Daily at 06:15 UTC (offset from the hour to reduce Action load spikes).
- cron: "15 6 * * *"
# No workflow_dispatch: a branch-selected manual run would execute that
# branch's workflow body with issues:write / pull-requests:write, bypassing
- # default-branch review. Schedule-only keeps the trusted revision on main.
+ # default-branch review. Schedule-only keeps the trusted revision on `dev`.
permissions:
issues: write
diff --git a/AGENTS.md b/AGENTS.md
index 8708827227b..ea56c79a958 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -351,10 +351,8 @@ than nudged.
they were deleted; `tests/ci-workflows/repo-hygiene.test.ts` now rejects
those folders. When the PR resolves an issue, add
`Closes #` to link it. GitHub auto-closes the linked issue only
- when the PR merges into the default branch (`main`); PRs here target
- `dev`, so close the issue manually once the change is on `dev` while `main`
- remains the default branch. After the maintainer switches the default to `dev`,
- GitHub can close it automatically when the linked pull request merges.
+ when the PR merges into the default branch, which is `dev`, so a linked issue
+ closes when its pull request merges.
- **Landing another author's work:** reimplementing, superseding, carrying, or
rebasing someone else's pull request requires a `Co-authored-by` trailer
naming that author, in the description or in a branch commit so it survives
@@ -396,12 +394,14 @@ than nudged.
## Branch policy
-- `dev` — the single development and integration branch and the target for every
- ordinary pull request. Preview and stable releases are built from eligible
- commits on this line, with versions stamped in build checkouts.
-- `main` and `preview` — protected historical branches retained for migration and
- recovery. They are not integration or release promotion targets. Switching the
- repository default branch to `dev` is a separate maintainer-controlled setting.
+- `dev` — the single development and integration branch, the repository default
+ branch, and the target for every ordinary pull request. Preview and stable
+ releases are built from eligible commits on this line, with versions stamped in
+ build checkouts.
+- `main` and `preview` were deleted once the single-branch model was in place.
+ Their released history remains reachable through tags; they are not
+ integration, promotion, or review targets, and no workflow may trigger on or
+ check out either branch.
Bun-native TypeScript on `dev` is the only runtime line. If native code
returns, the expectation is an incremental module (for example Rust via N-API)
@@ -416,9 +416,9 @@ Rebase pull requests are welcome. Bringing a stale branch onto the current head
is ordinary maintenance — open it as a normal pull request and name the source
commits in the description.
-The **`enforce-target`** CI check rejects pull requests whose head
-ancestry sits on the **`main`** tip while far behind **`dev`**, and rejects
-empty, thin, or malformed descriptions. If changed paths include files under
+The **`enforce-target`** CI check rejects pull requests whose base is not
+**`dev`** (stacked children excepted), and rejects empty, thin, or malformed
+descriptions. If changed paths include files under
`gui/`, include a screenshot of the UI change in the description; the check
re-runs on description edits until the screenshot is present. Drag the image
into the description editor rather than committing it, or, when uploading from
@@ -440,16 +440,15 @@ local-validation box is an author attestation only — fork contributors cannot
repository CI; a maintainer has to — so the gate never disproves it; a new
push still resets every box. A disproved claim unticks the matching box and
keeps the PR a draft.
-Authors with repository push permission skip the ancestry heuristic only. As with approval requirements in
-[`MAINTAINERS.md`](./MAINTAINERS.md), the ancestry heuristic is a CI check
-rather than a branch rule. The branches themselves are protected: `dev`,
-`main`, and `preview` each require a pull request and block force-pushes and deletion.
+As with approval requirements in [`MAINTAINERS.md`](./MAINTAINERS.md), the
+wrong-base rule is a CI check rather than a branch rule. The branch itself is
+protected: `dev` requires a pull request and blocks force-pushes and deletion.
For `dev` only, a current maintainer with GitHub `maintain` or `admin` access may
explicitly integrate through a PR without another maintainer approval, including
their own PR, under the policy in `MAINTAINERS.md`. Record the decision and exact-head
CI evidence; keep outstanding maintainer objections and security review separate.
The bypass is PR-only, so a direct push to `dev` remains rejected regardless of
-local hook settings. Contributor review and `main`/`preview` rules remain unchanged.
+local hook settings. Contributor review rules remain unchanged.
[`MAINTAINERS.md`](./MAINTAINERS.md) is authoritative for review and merge
policy (approvals, CI requirements, security review, promotion). This file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index bbcd248f8f8..a5944a82f56 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,9 +15,13 @@ Thanks for helping with opencodex.
## Branches
-- `dev` — the only integration target for pull requests.
-- `main` — releases only; moves by maintainer-controlled promotion from `dev`.
-- `preview` — prerelease train.
+- `dev` — the only integration target for pull requests and the repository
+ default branch. Stable and preview releases are cut from eligible `dev`
+ commits by the release workflow, which stamps the version into build
+ checkouts.
+- `main` and `preview` were deleted once the single-branch model was in place.
+ Their released history remains reachable through tags; neither is an
+ integration, promotion, or review target.
The `dev2-go` Go native-port line has been retired. Its history is archived at
[lidge-jun/opencodex-go-archive](https://github.com/lidge-jun/opencodex-go-archive),
@@ -40,7 +44,7 @@ Bun through that bundled dependency.
- Pull requests run **only the fast Ubuntu subset**.
- Full cross-platform (macOS/Windows) CI runs **only** via manual
- `workflow_dispatch` and on push to `main`/`preview` (release lines).
+ `workflow_dispatch` on `dev`; there is no push trigger.
- **Never** add a `dev` push trigger, or `pull_request` runs for macOS/Windows
jobs, to any workflow. PRs that change this policy will be closed.
@@ -72,8 +76,8 @@ A ready-for-review PR is the author's claim that the change is complete, underst
The suite uses Bun 1.4.4 (`testRunnerBun`) while the shipped runtime is 1.4.4.
`scripts/test.ts` finds a 1.4.4 binary on PATH or in `~/.bun/bin`, or uses
`OCX_TEST_RUNNER_BUN`; install that version locally if it is missing.
-The roles remain independently checked even when their versions match. Promotion requires
-a successful full cross-platform `lane=all` run on the candidate head.
+The roles remain independently checked even when their versions match. Release selection
+requires a successful full cross-platform `lane=all` run on the exact candidate `dev` SHA.
Run `bun run test` before review readiness. If the full local suite is too costly
for the task or available resources, run at least focused regression tests for
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
index 69a4d41bd64..34fd9d1caae 100644
--- a/MAINTAINERS.md
+++ b/MAINTAINERS.md
@@ -30,9 +30,9 @@ when a maintainer steps down.
- Pull requests target `dev`, the only development and integration line. The
target-branch check accepts `dev` alone.
-- The **`enforce-target`** CI check rejects pull requests whose head
- ancestry sits on the **`main`** tip while far behind **`dev`**, and rejects
- empty, thin, or malformed descriptions; PRs that change files under `gui/`
+- The **`enforce-target`** CI check rejects pull requests whose base is not
+ **`dev`** (stacked children excepted), and rejects empty, thin, or malformed
+ descriptions; PRs that change files under `gui/`
must include a screenshot of the UI change in the description. Drag the image
into the description instead of committing it to the PR branch; command-line
uploads use the `pr-assets` branch and a commit-SHA link.
@@ -57,9 +57,8 @@ when a maintainer steps down.
never disproves it;
a new push still resets every box. A disproved claim unticks the matching
box and keeps the PR a draft.
- Authors with repository push permission skip the ancestry heuristic only. As
- with the approval requirement above, this part is enforced by convention;
- the ruleset does not check ancestry (see the note under the change log).
+ As with the approval requirement above, the wrong-base rule is enforced by CI
+ rather than by the ruleset.
- Pull requests require successful required CI checks before merge. Contributor pull requests
normally require approval from at least one maintainer other than the author.
- **Batched merges.** A pull request's own CI is the fast lane by default: `gates` plus
@@ -78,9 +77,9 @@ when a maintainer steps down.
This is maintainer integration, not a self-approval or an independent review. Outstanding
maintainer change requests must still be resolved or explicitly withdrawn. Technical review,
attribution, documentation and security-review duties remain in force.
-- The maintainer-integration exception applies only to `dev`. It does not change review rules
- for `main` or `preview`, grant contributor authors approval authority, or permit direct pushes,
- force-pushes or branch deletion. Authors do not submit approving reviews of their own work.
+- The maintainer-integration exception applies only to `dev`. It does not grant contributor
+ authors approval authority or permit direct pushes, force-pushes or branch deletion. Authors do
+ not submit approving reviews of their own work.
- Authentication, credential handling, GitHub Actions, release automation, dependency installation,
and other security-boundary changes require explicit security review.
- A new or promoted provider preset is a credential-destination change. Before merge it needs the
@@ -101,8 +100,9 @@ when a maintainer steps down.
`dev` commit with successful full manual cross-platform CI; the workflow stamps the
release version into build checkouts instead of committing a pre-release version bump
or promoting a branch. Releases share one concurrency group and preserve the global
- version ordering. `main` and `preview` remain protected historical branches during
- migration, not release targets.
+ version ordering. The `main` and `preview` branches were deleted after the
+ single-branch model was in place; released history remains reachable through
+ tags, and neither branch is a release target.
- Publication remains disabled until the coordinator completes the cutover checks,
including the reviewed legacy lineage baseline, npm trusted-publisher configuration,
default branch and rulesets, Pages settings, and a hosted dry-run. The variable
@@ -146,7 +146,7 @@ Adding or removing a maintainer requires:
- 2026-09-06 — The owner authorized explicit maintainer integration into `dev` without a second
maintainer approval. Both current maintainers have `admin` access. The dev-only PR bypass
includes GitHub's `admin` and `maintain` roles; `write` access alone is insufficient. Contributor
- review remains the default and the `main`/`preview` rules are unchanged. The optional
+ review remained the default; the former `main`/`preview` branches were later retired. The optional
`scripts/ci/assert-mergeable-review.sh --maintainer-integration [repo]` path checks
the authenticated actor against the trusted `dev` roster and live repository permissions,
preserves outstanding maintainer objections, and binds its result to the current head and base.
@@ -195,10 +195,10 @@ Adding or removing a maintainer requires:
this addition does not widen the review surface for them.
Code-owner approval and the maintainer-approval requirement above are both
- enforced, not conventions. `dev`, `main`, and `preview` each carry an active
- repository ruleset — the classic `/branches/{branch}/protection` endpoint
- returns 404 for them, which is why this file long described the repository as
- unprotected. `Protect dev` (id 20763889) requires a pull request with one
+ enforced, not conventions. `dev` carries an active repository ruleset; the
+ classic `/branches/{branch}/protection` endpoint can return 404 for rulesets,
+ which is why this file long described the repository as unprotected.
+ `Protect dev` (id 20763889) requires a pull request with one
approving review, code-owner review, and extra approval for unattributed
changes, and it blocks deletion and non-fast-forward pushes. Allowed merge
methods are merge and squash; rebase merges are off.
diff --git a/README.md b/README.md
index ecfba0b6e7a..db98afcaf0a 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ and connect OpenCode, Pi, Qoder, WorkBuddy, Kilo, Cline, T3 Code and more throug
-
+
@@ -49,7 +49,7 @@ Pick a provider and go — same workflow, different brain.
-
+
|
@@ -61,7 +61,7 @@ Opus answers, then hands the task to a GPT-5.6 Sol subagent.
-
+
|
@@ -73,7 +73,7 @@ Sol drives the session and calls a Kimi K3 subagent.
-
+
|
@@ -206,7 +206,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/devlog/_plan/261108_dev_single_branch_release/020_stale_branch_cleanup.md b/devlog/_plan/261108_dev_single_branch_release/020_stale_branch_cleanup.md
new file mode 100644
index 00000000000..ed56b4cc6c6
--- /dev/null
+++ b/devlog/_plan/261108_dev_single_branch_release/020_stale_branch_cleanup.md
@@ -0,0 +1,93 @@
+# Stale `main`/`preview` reference cleanup
+
+**Trigger:** owner deleted the `main` and `preview` branches on 2026-11-09 and
+made `dev` the repository default. This unit already assumed a single-branch
+line; the branch deletion leaves references that now address branches that do
+not exist, or that describe a default-branch state which has changed.
+
+**Scope:** remove or correct only those stale references. This is a cleanup,
+not a CI-policy change.
+
+## What changes
+
+- **Dead workflow triggers.** `.github/workflows/codex-queue-helpers.yml` and
+ `.github/workflows/issue-quality-tests.yml` drop `push.branches: [main,
+ preview]` and keep `pull_request` (plus `workflow_dispatch` where present).
+ `cleanup-orphaned-workflows.yml` drops its one-time `push` on `main` and keeps
+ the daily `schedule`; `react-doctor.yml` drops its `push` on `main` and keeps
+ the PR scan. No dead push is replaced with a `dev` push — the CI policy
+ forbids a `dev` push trigger.
+- **Service lifecycle.** `service-lifecycle.yml` narrows PR `branches: [main,
+ dev]` to `[dev]`, which still excludes stacked-child head bases exactly as
+ before (the old list matched `main`, never stacked heads either).
+- **Trusted checkout refs.** `enforce-pr-target.yml` and `pr-hygiene.yml` select
+ the trusted script checkout with a fixed `dev` ref. `status` events in
+ `enforce-pr-target.yml` keep using `github.event.repository.default_branch`,
+ which is now `dev`. PR base/head never selects the ref.
+- **Obsolete main-ancestry policy.** `enforce-pr-target.yml`,
+ `.github/scripts/pr-quality.cjs` and `pr-quality-messages.cjs` lose the
+ `main...head` compare and the `wrong_ancestry` failure built on it. The
+ readiness claim check against the PR's own base (`behindBase`,
+ `READINESS_LATEST_DEV_BEHIND_MAX`, fail-closed on unknown) is separate policy
+ and stays. Stacked-child exemption stays.
+- **Comments/docs.** `ci.yml` default-branch comments, workflow loader comments
+ in `enforce-issue-quality.yml`, `pr-labeler.yml`, `stale-needs-info.yml`,
+ `closed-pr-branch-cleanup.yml`, `AGENTS.md`, `MAINTAINERS.md`,
+ `structure/ops/docs-and-release.md`, `structure/desktop-shell.md`, and the
+ workflow/doc tests that pin those strings.
+
+## What does not change
+
+Historical `main`/`preview` **tag** mappings, release-lineage policy, the
+`protected historical TAG mappings` in release evidence, lidge runner routing,
+the PR-only security boundary, the `status` default-branch semantics, stacked
+PR support, or the no-`dev`-push / no-PR-macOS-Windows CI policy.
+
+`ci.yml` is edited only in comments. Because the release evidence policy pins
+its blob, the final fingerprint entry is appended (history preserved), which
+also repairs the pre-existing drift from `28b38f9150` (that commit changed
+`ci.yml` without appending a policy entry).
+
+## Verification
+
+Failing-first: the workflow-trigger, trusted-checkout, and ancestry tests are
+updated to the intended contract and run red before the implementation. Then:
+targeted `node --test` script tests, targeted Bun workflow tests,
+`bun run typecheck`, `structure:check`, `test-layout`/ratchet/Lab guards,
+`privacy:scan`, `release-evidence.test.cjs` + `policy-check`, and
+`actionlint`.
+
+### Recorded results (this branch, based on `28b38f9150`)
+
+Failing-first: the workflow-trigger, trusted-checkout, default-branch and
+ancestry contract tests were rewritten to the intended behaviour and run red
+against the old tree before the implementation. After the implementation:
+
+| Check | Command | Result |
+| --- | --- | --- |
+| Typecheck | `bun run typecheck` | pass (2,341 files) |
+| Privacy | `bun run privacy:scan` | pass |
+| Structure SSOT | `bun run structure:check` | pass |
+| Lab / ratchet / layout guards | `bun test tests/lab/core-lab-boundary.test.ts tests/ci-workflows/file-size-ratchet.test.ts tests/test-layout.test.ts tests/test-layout-tooling.test.ts` | 63 pass |
+| Workflow suite | `bun test tests/ci-workflows` | 1,864 pass, 27 skip, 0 fail |
+| Script suites | `node --test` on `pr-quality`, `pr-quality-messages`, `enforce-pr-target`, `pr-hygiene`, `release-evidence` | 195 pass |
+| README parity | `bun test tests/ci-workflows/docs-readme-translation-parity.test.ts` and `docs-readme-memory-inventory.test.ts` | 53 + 33 pass |
+| Generated client matrix | `bun run docs:clients:check` | current |
+| Evidence policy | `node .github/scripts/release-evidence.cjs policy-check` | fingerprints match |
+| actionlint | changed workflows | only the two pre-existing findings, identical at `28b38f9150` (3× `SC2016` in `ci.yml`; `copilot-requests` scope unknown to actionlint in `enforce-issue-quality.yml`) |
+
+Consequences: the deleted branch pushes are gone rather than retargeted, so no
+`dev` push trigger was added; PR, schedule, and manual coverage is retained.
+`react-doctor.yml` loses its per-push health-score trend scan, and
+`service-lifecycle.yml` now fans out on `dev`-based pull requests only, exactly
+as it already excluded stacked-child bases. The release-evidence policy gains a
+new final fingerprint entry (earlier entries untouched), which also repairs the
+pre-existing `ci.yml` drift at `28b38f9150`.
+
+The `docs-site` build was run on this tree: 641 pages, 93,177 internal links
+checked, Pagefind index built.
+
+Not run: full `bun run test`. This change touches workflows, docs, and
+GitHub-script tests; the suites above cover every changed area, and the
+repository permits focused validation when a full local run is
+disproportionate. CI owns the remainder.
diff --git a/docs-site/src/content/docs/contributing.md b/docs-site/src/content/docs/contributing.md
index cf932e60e09..282ec9c1e79 100644
--- a/docs-site/src/content/docs/contributing.md
+++ b/docs-site/src/content/docs/contributing.md
@@ -139,10 +139,10 @@ as a substitute while the new publication gates remain unresolved.
## Branches
-- `dev` — the only integration target. Open your pull request here.
-- `main` and `preview` — protected historical branches retained for migration and recovery;
- neither is a release promotion target. Changing the repository default branch to `dev` is a
- separate maintainer-controlled cutover and has not been assumed here.
+- `dev` — the only integration target and the repository default branch. Open your pull
+ request here.
+- `main` and `preview` were deleted once the single-branch model was in place. Their released
+ history remains reachable through tags; neither is an integration or promotion target.
The `dev2-go` line that carried the Go native port has been retired, and the
dual-track carry policy with it. Its history is published read-only at
@@ -155,8 +155,10 @@ description.
## Pull requests
-- Target **`dev`**. Do not open feature or fix pull requests against **`main`**.
-- Branch from the current **`dev`** tip, not from **`main`**. The required **`enforce-target`** check rejects heads whose merge base sits on the **`main`** tip while the branch is far behind the pull request base (the failure mode seen in #644).
+- Target **`dev`**. The required **`enforce-target`** check rejects any other base
+ except a stacked child targeting another open pull request's head.
+- Branch from the current **`dev`** tip. A head that drifts too far behind `dev`
+ has its review-readiness latest-dev claim unticked rather than being rejected.
- Write a real description: a **Summary** of what changed and why, plus a **Test plan** (or equivalent substance). Empty bodies, placeholder-only text, and descriptions that use escaped `\n` instead of real line breaks fail the check.
- If the pull request changes files under `gui/`, include a screenshot of the UI change in the description; the `enforce-target` check re-runs on description edits until the screenshot is present. Drag the image into the description editor rather than committing it: an image on your branch rides the squash merge into `dev`. Maintainers uploading from the command line use the `pr-assets` branch and link by commit SHA.
- Workflow changes in this repository use **`pull_request_target`**. Updated enforcement logic applies only after the workflow reaches the repository default branch — the same operational caveat documented in #631.
@@ -164,14 +166,14 @@ description.
## Project maintainers
The current maintainers, their responsibilities, and the review and merge policy are documented in
-[`MAINTAINERS.md`](https://github.com/lidge-jun/opencodex/blob/main/MAINTAINERS.md). GitHub review
+[`MAINTAINERS.md`](https://github.com/lidge-jun/opencodex/blob/dev/MAINTAINERS.md). GitHub review
ownership for the repository and security-sensitive paths is declared in `.github/CODEOWNERS`.
Contributor pull requests normally need a maintainer's approval. A current maintainer with
GitHub `maintain` or `admin` access may explicitly integrate a PR into `dev`, including their
own, without a second maintainer approval. The decision and exact-head verification must be
recorded; CI, security review and outstanding maintainer objections still apply. This exception
-does not change `main`/`preview` review rules or allow direct pushes, force-pushes or deletion.
+does not allow direct pushes, force-pushes or deletion.
## Conventions
diff --git a/docs-site/src/content/docs/fr/contributing.md b/docs-site/src/content/docs/fr/contributing.md
index 0cea623c7ea..8a041cba0d3 100644
--- a/docs-site/src/content/docs/fr/contributing.md
+++ b/docs-site/src/content/docs/fr/contributing.md
@@ -90,10 +90,9 @@ une contribution normale ; indiquez les commits sources dans la description.
## Demandes d'extraction
-- Ciblez **`dev`**. N’ouvrez aucune pull request de fonctionnalité ou de correctif contre **`main`**.
-- Partez de la tête actuelle de **`dev`**, pas de **`main`**. Le contrôle obligatoire **`enforce-target`**
- rejette les branches dont la base de fusion se trouve sur la tête de **`main`** alors qu’elles sont très en
- retard sur la branche cible, le mode d’échec observé dans #644.
+- Ciblez **`dev`**, qui est aussi la branche par défaut du dépôt. **`main`** et **`preview`** ont été
+ supprimées une fois le modèle à branche unique en place. Le contrôle obligatoire **`enforce-target`**
+ rejette les pull requests dont la base n’est pas **`dev`** (les PR enfants empilées font exception).
- Rédigez une vraie description : un **Résumé** de la modification et de sa raison, ainsi qu’un **Plan de test**
ou un contenu équivalent. Les corps vides, les textes composés seulement d’espaces réservés et les descriptions
contenant des `\n` échappés au lieu de véritables sauts de ligne échouent au contrôle.
@@ -108,7 +107,7 @@ une contribution normale ; indiquez les commits sources dans la description.
## Responsables du projet
Les responsables actuels, leurs attributions et les règles de revue et de fusion sont décrits dans
-[`MAINTAINERS.md`](https://github.com/lidge-jun/opencodex/blob/main/MAINTAINERS.md). La propriété GitHub
+[`MAINTAINERS.md`](https://github.com/lidge-jun/opencodex/blob/dev/MAINTAINERS.md). La propriété GitHub
du dépôt et des chemins sensibles du point de vue de la sécurité est déclarée dans `.github/CODEOWNERS`.
## Conventions
diff --git a/docs-site/src/content/docs/fr/guides/remote-hub.md b/docs-site/src/content/docs/fr/guides/remote-hub.md
index aab597faa75..1d3e22389ef 100644
--- a/docs-site/src/content/docs/fr/guides/remote-hub.md
+++ b/docs-site/src/content/docs/fr/guides/remote-hub.md
@@ -158,7 +158,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/docs-site/src/content/docs/fr/reference/client-support.md b/docs-site/src/content/docs/fr/reference/client-support.md
index 1c9ca908c40..92087d244c4 100644
--- a/docs-site/src/content/docs/fr/reference/client-support.md
+++ b/docs-site/src/content/docs/fr/reference/client-support.md
@@ -18,34 +18,34 @@ opencodex est une passerelle locale unique pour vos outils de code IA et vos mod
| Client | Natif | Export de configuration | Intégration de fichier gérée | Protocole entrant | Niveau | Vérifié à l’exécution | Remarques |
| --- | --- | --- | --- | --- | --- | --- | --- |
-| Codex (CLI, app, SDK) | Oui | — | — | Responses (revu) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | Configuré par opencodex lui-même ; aucun fichier de configuration exporté. [guide](/fr/guides/codex-integration/) |
-| Claude Code | Oui | — | — | Anthropic Messages (revu) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/claude-integration/claude-cli.test.ts)) | — | Configuré par opencodex lui-même ; aucun fichier de configuration exporté. [guide](/fr/guides/claude-code/) |
+| Codex (CLI, app, SDK) | Oui | — | — | Responses (revu) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | Configuré par opencodex lui-même ; aucun fichier de configuration exporté. [guide](/fr/guides/codex-integration/) |
+| Claude Code | Oui | — | — | Anthropic Messages (revu) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/claude-integration/claude-cli.test.ts)) | — | Configuré par opencodex lui-même ; aucun fichier de configuration exporté. [guide](/fr/guides/claude-code/) |
| Claude Desktop | Oui | — | — | Anthropic Messages (revu) | implemented | — | Configuré par opencodex lui-même ; aucun fichier de configuration exporté. |
-| Grok Build | Oui | — | — | Responses (revu) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/providers/xai/grok-config-inject.test.ts)) | — | Configuré par opencodex lui-même ; aucun fichier de configuration exporté. [guide](/fr/guides/grok-build/) |
-| Qoder | — | JSON | Oui | Compatible OpenAI (point de terminaison choisi par le client) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/qoder-client.test.ts)) | — | Écoute locale uniquement. |
+| Grok Build | Oui | — | — | Responses (revu) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/providers/xai/grok-config-inject.test.ts)) | — | Configuré par opencodex lui-même ; aucun fichier de configuration exporté. [guide](/fr/guides/grok-build/) |
+| Qoder | — | JSON | Oui | Compatible OpenAI (point de terminaison choisi par le client) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/qoder-client.test.ts)) | — | Écoute locale uniquement. |
| Qoder CN | — | JSON | Oui | Compatible OpenAI (point de terminaison choisi par le client) | implemented | — | Écoute locale uniquement. |
-| WorkBuddy | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/agent-clients.test.ts)) | — | Écoute locale uniquement. L’application exécute d’abord une vérification propre au client et peut refuser. |
+| WorkBuddy | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/agent-clients.test.ts)) | — | Écoute locale uniquement. L’application exécute d’abord une vérification propre au client et peut refuser. |
| WorkBuddy AI | — | JSON | Oui | Chat Completions | implemented | — | Écoute locale uniquement. L’application exécute d’abord une vérification propre au client et peut refuser. |
-| OpenCode | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | L’export prend aussi en charge une écoute distante (il ajoute l’en-tête de clé API). [guide](/fr/guides/opencode/) |
-| Pi | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Écoute locale uniquement. [guide](/fr/guides/pi/) |
-| Oh My Pi (omp) | — | YAML | Oui | Chat Completions; Responses (modèles OpenAI natifs uniquement) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Écoute locale uniquement. Ne modifie que son propre bloc YAML. |
-| Hermes | — | YAML | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/hermes-catalog-refresh.test.ts)) | — | L’export prend aussi en charge une écoute distante (il ajoute l’en-tête de clé API). Ne modifie que son propre bloc YAML. |
-| OpenClaw | — | JSON5 | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/gui/integrations-invariants.test.ts)) | — | L’export prend aussi en charge une écoute distante (il ajoute l’en-tête de clé API). |
-| Kimi CLI | — | TOML | Oui | Compatible OpenAI (point de terminaison choisi par le client) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export-new-clients.test.ts)) | — | Écoute locale uniquement. |
-| Gajae | — | YAML | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-modality-enum.test.ts)) | — | Écoute locale uniquement. |
-| DSH | — | YAML | Oui | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Écoute locale uniquement. Écrit dans le magasin de fournisseurs actuel du client. Ne modifie que son propre bloc YAML. Les écritures passent par un fichier de verrou placé à côté de la configuration. |
+| OpenCode | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | L’export prend aussi en charge une écoute distante (il ajoute l’en-tête de clé API). [guide](/fr/guides/opencode/) |
+| Pi | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Écoute locale uniquement. [guide](/fr/guides/pi/) |
+| Oh My Pi (omp) | — | YAML | Oui | Chat Completions; Responses (modèles OpenAI natifs uniquement) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Écoute locale uniquement. Ne modifie que son propre bloc YAML. |
+| Hermes | — | YAML | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/hermes-catalog-refresh.test.ts)) | — | L’export prend aussi en charge une écoute distante (il ajoute l’en-tête de clé API). Ne modifie que son propre bloc YAML. |
+| OpenClaw | — | JSON5 | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/gui/integrations-invariants.test.ts)) | — | L’export prend aussi en charge une écoute distante (il ajoute l’en-tête de clé API). |
+| Kimi CLI | — | TOML | Oui | Compatible OpenAI (point de terminaison choisi par le client) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export-new-clients.test.ts)) | — | Écoute locale uniquement. |
+| Gajae | — | YAML | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-modality-enum.test.ts)) | — | Écoute locale uniquement. |
+| DSH | — | YAML | Oui | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Écoute locale uniquement. Écrit dans le magasin de fournisseurs actuel du client. Ne modifie que son propre bloc YAML. Les écritures passent par un fichier de verrou placé à côté de la configuration. |
| MCode | — | YAML | Oui | Anthropic Messages | implemented | — | Écoute locale uniquement. Les écritures passent par un fichier de verrou placé à côté de la configuration. |
-| ZCode | — | JSON | Oui | Responses (revu) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/integrations-current-store.test.ts)) | — | Écoute locale uniquement. Écrit dans le magasin de fournisseurs actuel du client. Le client choisit le point de terminaison à partir de ce réglage (vérifié en revue d’après le comportement documenté du client). |
-| Command Code | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/command-code-client.test.ts)) | — | Écoute locale uniquement. Les écritures passent par un fichier de verrou placé à côté de la configuration. |
-| Prime | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/prime-client.test.ts)) | — | Écoute locale uniquement. |
-| Aside | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | Écoute locale uniquement. |
-| Raycast | — | YAML | Oui | Chat Completions (revu) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/raycast-client.test.ts)) | — | Écoute locale uniquement. Le client choisit le point de terminaison à partir de ce réglage (vérifié en revue d’après le comportement documenté du client). |
-| omo | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/omo-client.test.ts)) | — | Écoute locale uniquement. |
-| Cline | — | JSON | Oui | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/cline-client.test.ts)) | — | Écoute locale uniquement. Les écritures passent par un fichier de verrou placé à côté de la configuration. |
-| Kilo Code | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-reasoning-controls.test.ts)) | — | L’export prend aussi en charge une écoute distante (il ajoute l’en-tête de clé API). |
-| Factory Droid | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/droid-client.test.ts)) | — | Écoute locale uniquement. [guide](/fr/guides/factory-droid/) |
-| Gentle Shell | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/gentle-shell-client.test.ts)) | — | Écoute locale uniquement. |
-| T3 Code | — | JSON | Oui | Anthropic Messages | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/t3code-client.test.ts)) | — | Écoute locale uniquement. L’application exécute d’abord une vérification propre au client et peut refuser. |
+| ZCode | — | JSON | Oui | Responses (revu) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/integrations-current-store.test.ts)) | — | Écoute locale uniquement. Écrit dans le magasin de fournisseurs actuel du client. Le client choisit le point de terminaison à partir de ce réglage (vérifié en revue d’après le comportement documenté du client). |
+| Command Code | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/command-code-client.test.ts)) | — | Écoute locale uniquement. Les écritures passent par un fichier de verrou placé à côté de la configuration. |
+| Prime | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/prime-client.test.ts)) | — | Écoute locale uniquement. |
+| Aside | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | Écoute locale uniquement. |
+| Raycast | — | YAML | Oui | Chat Completions (revu) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/raycast-client.test.ts)) | — | Écoute locale uniquement. Le client choisit le point de terminaison à partir de ce réglage (vérifié en revue d’après le comportement documenté du client). |
+| omo | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/omo-client.test.ts)) | — | Écoute locale uniquement. |
+| Cline | — | JSON | Oui | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/cline-client.test.ts)) | — | Écoute locale uniquement. Les écritures passent par un fichier de verrou placé à côté de la configuration. |
+| Kilo Code | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-reasoning-controls.test.ts)) | — | L’export prend aussi en charge une écoute distante (il ajoute l’en-tête de clé API). |
+| Factory Droid | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/droid-client.test.ts)) | — | Écoute locale uniquement. [guide](/fr/guides/factory-droid/) |
+| Gentle Shell | — | JSON | Oui | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/gentle-shell-client.test.ts)) | — | Écoute locale uniquement. |
+| T3 Code | — | JSON | Oui | Anthropic Messages | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/t3code-client.test.ts)) | — | Écoute locale uniquement. L’application exécute d’abord une vérification propre au client et peut refuser. |
## Points de terminaison entrants
diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md
index 380a99d72c1..18dd72b84e5 100644
--- a/docs-site/src/content/docs/guides/providers.md
+++ b/docs-site/src/content/docs/guides/providers.md
@@ -797,7 +797,7 @@ preserves those requested tiers; any backend-specific normalization remains Clin
available in the Cline IDE/CLI, not through the API; `minimax/minimax-m2.5` is the documented API
free-experimentation model.
-**OrcaRouter** ([sponsor](https://github.com/lidge-jun/opencodex/blob/main/SPONSORS.md)) is an
+**OrcaRouter** ([sponsor](https://github.com/lidge-jun/opencodex/blob/dev/SPONSORS.md)) is an
OpenAI-compatible gateway at `https://api.orcarouter.ai/v1` with vendor-namespaced model ids
(`openai/gpt-5.5`, `anthropic/claude-opus-4.8`, `deepseek/deepseek-v4-flash`, ...) and an adaptive
router, `orcarouter/auto`, that grades each prompt and picks the model. Create a key in the
@@ -919,7 +919,7 @@ retain the original stream. The protection does not change other providers or th
Replay requires explicit `store: false`, complete input, and client-executed tools only; a hosted
tool such as `web_search` prevents automatic replay even if no tool event was observed.
-**TokenLab** ([sponsor](https://github.com/lidge-jun/opencodex/blob/main/SPONSORS.md)) is an
+**TokenLab** ([sponsor](https://github.com/lidge-jun/opencodex/blob/dev/SPONSORS.md)) is an
OpenAI-compatible API gateway at [tokenlab.sh](https://tokenlab.sh/r/OPENCODEX),
operated by TOKENLAB AI INC.
Create a workspace [API key](https://tokenlab.sh/dashboard/api?tab=keys), then run
diff --git a/docs-site/src/content/docs/guides/remote-hub.md b/docs-site/src/content/docs/guides/remote-hub.md
index 8dfd7f0723a..1ad92279eef 100644
--- a/docs-site/src/content/docs/guides/remote-hub.md
+++ b/docs-site/src/content/docs/guides/remote-hub.md
@@ -560,8 +560,8 @@ input checks.
## Docker Compose
opencodex does not publish an official container image. The repository does maintain a source-build
-[`Dockerfile`](https://github.com/lidge-jun/opencodex/blob/main/Dockerfile),
-[`compose.yaml`](https://github.com/lidge-jun/opencodex/blob/main/compose.yaml), and a narrow
+[`Dockerfile`](https://github.com/lidge-jun/opencodex/blob/dev/Dockerfile),
+[`compose.yaml`](https://github.com/lidge-jun/opencodex/blob/dev/compose.yaml), and a narrow
`.dockerignore`. The build pins the multi-platform Bun 1.4.4 image index by digest, runs the proxy as
the non-root `bun` user, keeps the root filesystem read-only, drops Linux capabilities, and publishes
only the data listener on the host's `127.0.0.1:10100` by default. The foreground process uses
@@ -651,7 +651,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/docs-site/src/content/docs/ja/guides/remote-hub.md b/docs-site/src/content/docs/ja/guides/remote-hub.md
index 2b89e9c36c6..e73af96b026 100644
--- a/docs-site/src/content/docs/ja/guides/remote-hub.md
+++ b/docs-site/src/content/docs/ja/guides/remote-hub.md
@@ -159,7 +159,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/docs-site/src/content/docs/ja/reference/client-support.md b/docs-site/src/content/docs/ja/reference/client-support.md
index 4e5a7ce8e00..bef13c39dda 100644
--- a/docs-site/src/content/docs/ja/reference/client-support.md
+++ b/docs-site/src/content/docs/ja/reference/client-support.md
@@ -18,34 +18,34 @@ opencodex は、AI コーディングツールとモデルをつなぐ 1 つの
| クライアント | ネイティブ | 設定エクスポート | 管理ファイル連携 | 受信プロトコル | サポートレベル | 実行確認 | 備考 |
| --- | --- | --- | --- | --- | --- | --- | --- |
-| Codex (CLI, app, SDK) | はい | — | — | Responses (レビュー済み) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | opencodex が直接設定します。エクスポートされる設定ファイルはありません。 [ガイド](/ja/guides/codex-integration/) |
-| Claude Code | はい | — | — | Anthropic Messages (レビュー済み) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/claude-integration/claude-cli.test.ts)) | — | opencodex が直接設定します。エクスポートされる設定ファイルはありません。 [ガイド](/ja/guides/claude-code/) |
+| Codex (CLI, app, SDK) | はい | — | — | Responses (レビュー済み) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | opencodex が直接設定します。エクスポートされる設定ファイルはありません。 [ガイド](/ja/guides/codex-integration/) |
+| Claude Code | はい | — | — | Anthropic Messages (レビュー済み) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/claude-integration/claude-cli.test.ts)) | — | opencodex が直接設定します。エクスポートされる設定ファイルはありません。 [ガイド](/ja/guides/claude-code/) |
| Claude Desktop | はい | — | — | Anthropic Messages (レビュー済み) | implemented | — | opencodex が直接設定します。エクスポートされる設定ファイルはありません。 |
-| Grok Build | はい | — | — | Responses (レビュー済み) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/providers/xai/grok-config-inject.test.ts)) | — | opencodex が直接設定します。エクスポートされる設定ファイルはありません。 [ガイド](/ja/guides/grok-build/) |
-| Qoder | — | JSON | はい | OpenAI 互換(エンドポイントはクライアントが選択) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/qoder-client.test.ts)) | — | ローカルリスナーのみ。 |
+| Grok Build | はい | — | — | Responses (レビュー済み) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/providers/xai/grok-config-inject.test.ts)) | — | opencodex が直接設定します。エクスポートされる設定ファイルはありません。 [ガイド](/ja/guides/grok-build/) |
+| Qoder | — | JSON | はい | OpenAI 互換(エンドポイントはクライアントが選択) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/qoder-client.test.ts)) | — | ローカルリスナーのみ。 |
| Qoder CN | — | JSON | はい | OpenAI 互換(エンドポイントはクライアントが選択) | implemented | — | ローカルリスナーのみ。 |
-| WorkBuddy | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/agent-clients.test.ts)) | — | ローカルリスナーのみ。適用前にクライアント固有のチェックを実行し、拒否することがあります。 |
+| WorkBuddy | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/agent-clients.test.ts)) | — | ローカルリスナーのみ。適用前にクライアント固有のチェックを実行し、拒否することがあります。 |
| WorkBuddy AI | — | JSON | はい | Chat Completions | implemented | — | ローカルリスナーのみ。適用前にクライアント固有のチェックを実行し、拒否することがあります。 |
-| OpenCode | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | リモートリスナーにも対応します(API キーヘッダーを追加)。 [ガイド](/ja/guides/opencode/) |
-| Pi | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | ローカルリスナーのみ。 [ガイド](/ja/guides/pi/) |
-| Oh My Pi (omp) | — | YAML | はい | Chat Completions; Responses (ネイティブ OpenAI モデルのみ) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | ローカルリスナーのみ。自分の YAML ブロックだけを編集します。 |
-| Hermes | — | YAML | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/hermes-catalog-refresh.test.ts)) | — | リモートリスナーにも対応します(API キーヘッダーを追加)。自分の YAML ブロックだけを編集します。 |
-| OpenClaw | — | JSON5 | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/gui/integrations-invariants.test.ts)) | — | リモートリスナーにも対応します(API キーヘッダーを追加)。 |
-| Kimi CLI | — | TOML | はい | OpenAI 互換(エンドポイントはクライアントが選択) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export-new-clients.test.ts)) | — | ローカルリスナーのみ。 |
-| Gajae | — | YAML | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-modality-enum.test.ts)) | — | ローカルリスナーのみ。 |
-| DSH | — | YAML | はい | Responses | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | ローカルリスナーのみ。クライアントの現在のプロバイダーストアに書き込みます。自分の YAML ブロックだけを編集します。設定ファイル横のロックファイルで書き込みを調整します。 |
+| OpenCode | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | リモートリスナーにも対応します(API キーヘッダーを追加)。 [ガイド](/ja/guides/opencode/) |
+| Pi | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | ローカルリスナーのみ。 [ガイド](/ja/guides/pi/) |
+| Oh My Pi (omp) | — | YAML | はい | Chat Completions; Responses (ネイティブ OpenAI モデルのみ) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | ローカルリスナーのみ。自分の YAML ブロックだけを編集します。 |
+| Hermes | — | YAML | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/hermes-catalog-refresh.test.ts)) | — | リモートリスナーにも対応します(API キーヘッダーを追加)。自分の YAML ブロックだけを編集します。 |
+| OpenClaw | — | JSON5 | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/gui/integrations-invariants.test.ts)) | — | リモートリスナーにも対応します(API キーヘッダーを追加)。 |
+| Kimi CLI | — | TOML | はい | OpenAI 互換(エンドポイントはクライアントが選択) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export-new-clients.test.ts)) | — | ローカルリスナーのみ。 |
+| Gajae | — | YAML | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-modality-enum.test.ts)) | — | ローカルリスナーのみ。 |
+| DSH | — | YAML | はい | Responses | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | ローカルリスナーのみ。クライアントの現在のプロバイダーストアに書き込みます。自分の YAML ブロックだけを編集します。設定ファイル横のロックファイルで書き込みを調整します。 |
| MCode | — | YAML | はい | Anthropic Messages | implemented | — | ローカルリスナーのみ。設定ファイル横のロックファイルで書き込みを調整します。 |
-| ZCode | — | JSON | はい | Responses (レビュー済み) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/integrations-current-store.test.ts)) | — | ローカルリスナーのみ。クライアントの現在のプロバイダーストアに書き込みます。クライアントがこの設定からエンドポイントを選びます(クライアントの文書化された動作に基づきレビュー済み)。 |
-| Command Code | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/command-code-client.test.ts)) | — | ローカルリスナーのみ。設定ファイル横のロックファイルで書き込みを調整します。 |
-| Prime | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/prime-client.test.ts)) | — | ローカルリスナーのみ。 |
-| Aside | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | ローカルリスナーのみ。 |
-| Raycast | — | YAML | はい | Chat Completions (レビュー済み) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/raycast-client.test.ts)) | — | ローカルリスナーのみ。クライアントがこの設定からエンドポイントを選びます(クライアントの文書化された動作に基づきレビュー済み)。 |
-| omo | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/omo-client.test.ts)) | — | ローカルリスナーのみ。 |
-| Cline | — | JSON | はい | Responses | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/cline-client.test.ts)) | — | ローカルリスナーのみ。設定ファイル横のロックファイルで書き込みを調整します。 |
-| Kilo Code | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-reasoning-controls.test.ts)) | — | リモートリスナーにも対応します(API キーヘッダーを追加)。 |
-| Factory Droid | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/droid-client.test.ts)) | — | ローカルリスナーのみ。 [ガイド](/ja/guides/factory-droid/) |
-| Gentle Shell | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/gentle-shell-client.test.ts)) | — | ローカルリスナーのみ。 |
-| T3 Code | — | JSON | はい | Anthropic Messages | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/t3code-client.test.ts)) | — | ローカルリスナーのみ。適用前にクライアント固有のチェックを実行し、拒否することがあります。 |
+| ZCode | — | JSON | はい | Responses (レビュー済み) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/integrations-current-store.test.ts)) | — | ローカルリスナーのみ。クライアントの現在のプロバイダーストアに書き込みます。クライアントがこの設定からエンドポイントを選びます(クライアントの文書化された動作に基づきレビュー済み)。 |
+| Command Code | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/command-code-client.test.ts)) | — | ローカルリスナーのみ。設定ファイル横のロックファイルで書き込みを調整します。 |
+| Prime | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/prime-client.test.ts)) | — | ローカルリスナーのみ。 |
+| Aside | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | ローカルリスナーのみ。 |
+| Raycast | — | YAML | はい | Chat Completions (レビュー済み) | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/raycast-client.test.ts)) | — | ローカルリスナーのみ。クライアントがこの設定からエンドポイントを選びます(クライアントの文書化された動作に基づきレビュー済み)。 |
+| omo | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/omo-client.test.ts)) | — | ローカルリスナーのみ。 |
+| Cline | — | JSON | はい | Responses | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/cline-client.test.ts)) | — | ローカルリスナーのみ。設定ファイル横のロックファイルで書き込みを調整します。 |
+| Kilo Code | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-reasoning-controls.test.ts)) | — | リモートリスナーにも対応します(API キーヘッダーを追加)。 |
+| Factory Droid | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/droid-client.test.ts)) | — | ローカルリスナーのみ。 [ガイド](/ja/guides/factory-droid/) |
+| Gentle Shell | — | JSON | はい | Chat Completions | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/gentle-shell-client.test.ts)) | — | ローカルリスナーのみ。 |
+| T3 Code | — | JSON | はい | Anthropic Messages | test-covered ([テスト](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/t3code-client.test.ts)) | — | ローカルリスナーのみ。適用前にクライアント固有のチェックを実行し、拒否することがあります。 |
## 受信エンドポイント
diff --git a/docs-site/src/content/docs/ko/guides/remote-hub.md b/docs-site/src/content/docs/ko/guides/remote-hub.md
index eaa3558e860..204cefb5ef1 100644
--- a/docs-site/src/content/docs/ko/guides/remote-hub.md
+++ b/docs-site/src/content/docs/ko/guides/remote-hub.md
@@ -334,7 +334,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/docs-site/src/content/docs/ko/reference/client-support.md b/docs-site/src/content/docs/ko/reference/client-support.md
index a6730e905f0..2e52ed4cd43 100644
--- a/docs-site/src/content/docs/ko/reference/client-support.md
+++ b/docs-site/src/content/docs/ko/reference/client-support.md
@@ -18,34 +18,34 @@ opencodex는 AI 코딩 도구와 모델을 잇는 하나의 로컬 게이트웨
| 클라이언트 | 네이티브 | 설정 내보내기 | 관리형 파일 연동 | 수신 프로토콜 | 지원 수준 | 실행 검증 | 참고 |
| --- | --- | --- | --- | --- | --- | --- | --- |
-| Codex (CLI, app, SDK) | 예 | — | — | Responses (검토됨) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | opencodex가 직접 설정하며 내보내는 설정 파일은 없습니다. [가이드](/ko/guides/codex-integration/) |
-| Claude Code | 예 | — | — | Anthropic Messages (검토됨) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/claude-integration/claude-cli.test.ts)) | — | opencodex가 직접 설정하며 내보내는 설정 파일은 없습니다. [가이드](/ko/guides/claude-code/) |
+| Codex (CLI, app, SDK) | 예 | — | — | Responses (검토됨) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | opencodex가 직접 설정하며 내보내는 설정 파일은 없습니다. [가이드](/ko/guides/codex-integration/) |
+| Claude Code | 예 | — | — | Anthropic Messages (검토됨) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/claude-integration/claude-cli.test.ts)) | — | opencodex가 직접 설정하며 내보내는 설정 파일은 없습니다. [가이드](/ko/guides/claude-code/) |
| Claude Desktop | 예 | — | — | Anthropic Messages (검토됨) | implemented | — | opencodex가 직접 설정하며 내보내는 설정 파일은 없습니다. |
-| Grok Build | 예 | — | — | Responses (검토됨) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/providers/xai/grok-config-inject.test.ts)) | — | opencodex가 직접 설정하며 내보내는 설정 파일은 없습니다. [가이드](/ko/guides/grok-build/) |
-| Qoder | — | JSON | 예 | OpenAI 호환(엔드포인트는 클라이언트가 선택) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/qoder-client.test.ts)) | — | 로컬 리스너 전용. |
+| Grok Build | 예 | — | — | Responses (검토됨) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/providers/xai/grok-config-inject.test.ts)) | — | opencodex가 직접 설정하며 내보내는 설정 파일은 없습니다. [가이드](/ko/guides/grok-build/) |
+| Qoder | — | JSON | 예 | OpenAI 호환(엔드포인트는 클라이언트가 선택) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/qoder-client.test.ts)) | — | 로컬 리스너 전용. |
| Qoder CN | — | JSON | 예 | OpenAI 호환(엔드포인트는 클라이언트가 선택) | implemented | — | 로컬 리스너 전용. |
-| WorkBuddy | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/agent-clients.test.ts)) | — | 로컬 리스너 전용. 적용 전에 클라이언트별 검사를 실행하며 거부할 수 있습니다. |
+| WorkBuddy | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/agent-clients.test.ts)) | — | 로컬 리스너 전용. 적용 전에 클라이언트별 검사를 실행하며 거부할 수 있습니다. |
| WorkBuddy AI | — | JSON | 예 | Chat Completions | implemented | — | 로컬 리스너 전용. 적용 전에 클라이언트별 검사를 실행하며 거부할 수 있습니다. |
-| OpenCode | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 원격 리스너도 지원합니다(API 키 헤더를 추가). [가이드](/ko/guides/opencode/) |
-| Pi | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 로컬 리스너 전용. [가이드](/ko/guides/pi/) |
-| Oh My Pi (omp) | — | YAML | 예 | Chat Completions; Responses (네이티브 OpenAI 모델만) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 로컬 리스너 전용. 자기 YAML 블록만 수정합니다. |
-| Hermes | — | YAML | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/hermes-catalog-refresh.test.ts)) | — | 원격 리스너도 지원합니다(API 키 헤더를 추가). 자기 YAML 블록만 수정합니다. |
-| OpenClaw | — | JSON5 | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/gui/integrations-invariants.test.ts)) | — | 원격 리스너도 지원합니다(API 키 헤더를 추가). |
-| Kimi CLI | — | TOML | 예 | OpenAI 호환(엔드포인트는 클라이언트가 선택) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export-new-clients.test.ts)) | — | 로컬 리스너 전용. |
-| Gajae | — | YAML | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-modality-enum.test.ts)) | — | 로컬 리스너 전용. |
-| DSH | — | YAML | 예 | Responses | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 로컬 리스너 전용. 클라이언트의 현재 provider 저장소에 씁니다. 자기 YAML 블록만 수정합니다. 설정 파일 옆 잠금 파일로 쓰기를 조율합니다. |
+| OpenCode | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 원격 리스너도 지원합니다(API 키 헤더를 추가). [가이드](/ko/guides/opencode/) |
+| Pi | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 로컬 리스너 전용. [가이드](/ko/guides/pi/) |
+| Oh My Pi (omp) | — | YAML | 예 | Chat Completions; Responses (네이티브 OpenAI 모델만) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 로컬 리스너 전용. 자기 YAML 블록만 수정합니다. |
+| Hermes | — | YAML | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/hermes-catalog-refresh.test.ts)) | — | 원격 리스너도 지원합니다(API 키 헤더를 추가). 자기 YAML 블록만 수정합니다. |
+| OpenClaw | — | JSON5 | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/gui/integrations-invariants.test.ts)) | — | 원격 리스너도 지원합니다(API 키 헤더를 추가). |
+| Kimi CLI | — | TOML | 예 | OpenAI 호환(엔드포인트는 클라이언트가 선택) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export-new-clients.test.ts)) | — | 로컬 리스너 전용. |
+| Gajae | — | YAML | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-modality-enum.test.ts)) | — | 로컬 리스너 전용. |
+| DSH | — | YAML | 예 | Responses | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 로컬 리스너 전용. 클라이언트의 현재 provider 저장소에 씁니다. 자기 YAML 블록만 수정합니다. 설정 파일 옆 잠금 파일로 쓰기를 조율합니다. |
| MCode | — | YAML | 예 | Anthropic Messages | implemented | — | 로컬 리스너 전용. 설정 파일 옆 잠금 파일로 쓰기를 조율합니다. |
-| ZCode | — | JSON | 예 | Responses (검토됨) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/integrations-current-store.test.ts)) | — | 로컬 리스너 전용. 클라이언트의 현재 provider 저장소에 씁니다. 클라이언트가 이 설정값으로 엔드포인트를 고릅니다(클라이언트 문서 동작 기준으로 리뷰함). |
-| Command Code | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/command-code-client.test.ts)) | — | 로컬 리스너 전용. 설정 파일 옆 잠금 파일로 쓰기를 조율합니다. |
-| Prime | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/prime-client.test.ts)) | — | 로컬 리스너 전용. |
-| Aside | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | 로컬 리스너 전용. |
-| Raycast | — | YAML | 예 | Chat Completions (검토됨) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/raycast-client.test.ts)) | — | 로컬 리스너 전용. 클라이언트가 이 설정값으로 엔드포인트를 고릅니다(클라이언트 문서 동작 기준으로 리뷰함). |
-| omo | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/omo-client.test.ts)) | — | 로컬 리스너 전용. |
-| Cline | — | JSON | 예 | Responses | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/cline-client.test.ts)) | — | 로컬 리스너 전용. 설정 파일 옆 잠금 파일로 쓰기를 조율합니다. |
-| Kilo Code | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-reasoning-controls.test.ts)) | — | 원격 리스너도 지원합니다(API 키 헤더를 추가). |
-| Factory Droid | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/droid-client.test.ts)) | — | 로컬 리스너 전용. [가이드](/ko/guides/factory-droid/) |
-| Gentle Shell | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/gentle-shell-client.test.ts)) | — | 로컬 리스너 전용. |
-| T3 Code | — | JSON | 예 | Anthropic Messages | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/t3code-client.test.ts)) | — | 로컬 리스너 전용. 적용 전에 클라이언트별 검사를 실행하며 거부할 수 있습니다. |
+| ZCode | — | JSON | 예 | Responses (검토됨) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/integrations-current-store.test.ts)) | — | 로컬 리스너 전용. 클라이언트의 현재 provider 저장소에 씁니다. 클라이언트가 이 설정값으로 엔드포인트를 고릅니다(클라이언트 문서 동작 기준으로 리뷰함). |
+| Command Code | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/command-code-client.test.ts)) | — | 로컬 리스너 전용. 설정 파일 옆 잠금 파일로 쓰기를 조율합니다. |
+| Prime | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/prime-client.test.ts)) | — | 로컬 리스너 전용. |
+| Aside | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | 로컬 리스너 전용. |
+| Raycast | — | YAML | 예 | Chat Completions (검토됨) | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/raycast-client.test.ts)) | — | 로컬 리스너 전용. 클라이언트가 이 설정값으로 엔드포인트를 고릅니다(클라이언트 문서 동작 기준으로 리뷰함). |
+| omo | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/omo-client.test.ts)) | — | 로컬 리스너 전용. |
+| Cline | — | JSON | 예 | Responses | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/cline-client.test.ts)) | — | 로컬 리스너 전용. 설정 파일 옆 잠금 파일로 쓰기를 조율합니다. |
+| Kilo Code | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-reasoning-controls.test.ts)) | — | 원격 리스너도 지원합니다(API 키 헤더를 추가). |
+| Factory Droid | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/droid-client.test.ts)) | — | 로컬 리스너 전용. [가이드](/ko/guides/factory-droid/) |
+| Gentle Shell | — | JSON | 예 | Chat Completions | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/gentle-shell-client.test.ts)) | — | 로컬 리스너 전용. |
+| T3 Code | — | JSON | 예 | Anthropic Messages | test-covered ([테스트](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/t3code-client.test.ts)) | — | 로컬 리스너 전용. 적용 전에 클라이언트별 검사를 실행하며 거부할 수 있습니다. |
## 수신 엔드포인트
diff --git a/docs-site/src/content/docs/reference/client-support.md b/docs-site/src/content/docs/reference/client-support.md
index e1522a3b0de..a53f21b586d 100644
--- a/docs-site/src/content/docs/reference/client-support.md
+++ b/docs-site/src/content/docs/reference/client-support.md
@@ -18,34 +18,34 @@ opencodex is one local gateway for your AI coding tools and models. Some tools i
| Client | Native | Config export | Managed file integration | Inbound protocol | Support level | Runtime verified | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- |
-| Codex (CLI, app, SDK) | Yes | — | — | Responses (curated) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | Set up by opencodex itself; no exported config file. [guide](/guides/codex-integration/) |
-| Claude Code | Yes | — | — | Anthropic Messages (curated) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/claude-integration/claude-cli.test.ts)) | — | Set up by opencodex itself; no exported config file. [guide](/guides/claude-code/) |
+| Codex (CLI, app, SDK) | Yes | — | — | Responses (curated) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | Set up by opencodex itself; no exported config file. [guide](/guides/codex-integration/) |
+| Claude Code | Yes | — | — | Anthropic Messages (curated) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/claude-integration/claude-cli.test.ts)) | — | Set up by opencodex itself; no exported config file. [guide](/guides/claude-code/) |
| Claude Desktop | Yes | — | — | Anthropic Messages (curated) | implemented | — | Set up by opencodex itself; no exported config file. |
-| Grok Build | Yes | — | — | Responses (curated) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/providers/xai/grok-config-inject.test.ts)) | — | Set up by opencodex itself; no exported config file. [guide](/guides/grok-build/) |
-| Qoder | — | JSON | Yes | OpenAI-compatible (endpoint chosen by the client) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/qoder-client.test.ts)) | — | Local listener only. |
+| Grok Build | Yes | — | — | Responses (curated) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/providers/xai/grok-config-inject.test.ts)) | — | Set up by opencodex itself; no exported config file. [guide](/guides/grok-build/) |
+| Qoder | — | JSON | Yes | OpenAI-compatible (endpoint chosen by the client) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/qoder-client.test.ts)) | — | Local listener only. |
| Qoder CN | — | JSON | Yes | OpenAI-compatible (endpoint chosen by the client) | implemented | — | Local listener only. |
-| WorkBuddy | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/agent-clients.test.ts)) | — | Local listener only. Apply runs a client-specific check first and can refuse. |
+| WorkBuddy | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/agent-clients.test.ts)) | — | Local listener only. Apply runs a client-specific check first and can refuse. |
| WorkBuddy AI | — | JSON | Yes | Chat Completions | implemented | — | Local listener only. Apply runs a client-specific check first and can refuse. |
-| OpenCode | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | The exporter also supports a remote listener (it adds the API key header). [guide](/guides/opencode/) |
-| Pi | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Local listener only. [guide](/guides/pi/) |
-| Oh My Pi (omp) | — | YAML | Yes | Chat Completions; Responses (native OpenAI models only) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Local listener only. Edits only its own YAML block. |
-| Hermes | — | YAML | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/hermes-catalog-refresh.test.ts)) | — | The exporter also supports a remote listener (it adds the API key header). Edits only its own YAML block. |
-| OpenClaw | — | JSON5 | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/gui/integrations-invariants.test.ts)) | — | The exporter also supports a remote listener (it adds the API key header). |
-| Kimi CLI | — | TOML | Yes | OpenAI-compatible (endpoint chosen by the client) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export-new-clients.test.ts)) | — | Local listener only. |
-| Gajae | — | YAML | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-modality-enum.test.ts)) | — | Local listener only. |
-| DSH | — | YAML | Yes | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Local listener only. Writes the client's current provider store. Edits only its own YAML block. Writes are coordinated through a lock file next to the config. |
+| OpenCode | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | The exporter also supports a remote listener (it adds the API key header). [guide](/guides/opencode/) |
+| Pi | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Local listener only. [guide](/guides/pi/) |
+| Oh My Pi (omp) | — | YAML | Yes | Chat Completions; Responses (native OpenAI models only) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Local listener only. Edits only its own YAML block. |
+| Hermes | — | YAML | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/hermes-catalog-refresh.test.ts)) | — | The exporter also supports a remote listener (it adds the API key header). Edits only its own YAML block. |
+| OpenClaw | — | JSON5 | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/gui/integrations-invariants.test.ts)) | — | The exporter also supports a remote listener (it adds the API key header). |
+| Kimi CLI | — | TOML | Yes | OpenAI-compatible (endpoint chosen by the client) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export-new-clients.test.ts)) | — | Local listener only. |
+| Gajae | — | YAML | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-modality-enum.test.ts)) | — | Local listener only. |
+| DSH | — | YAML | Yes | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Local listener only. Writes the client's current provider store. Edits only its own YAML block. Writes are coordinated through a lock file next to the config. |
| MCode | — | YAML | Yes | Anthropic Messages | implemented | — | Local listener only. Writes are coordinated through a lock file next to the config. |
-| ZCode | — | JSON | Yes | Responses (curated) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/integrations-current-store.test.ts)) | — | Local listener only. Writes the client's current provider store. The client picks the endpoint from this setting (reviewed against the client's documented behavior). |
-| Command Code | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/command-code-client.test.ts)) | — | Local listener only. Writes are coordinated through a lock file next to the config. |
-| Prime | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/prime-client.test.ts)) | — | Local listener only. |
-| Aside | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | Local listener only. |
-| Raycast | — | YAML | Yes | Chat Completions (curated) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/raycast-client.test.ts)) | — | Local listener only. The client picks the endpoint from this setting (reviewed against the client's documented behavior). |
-| omo | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/omo-client.test.ts)) | — | Local listener only. |
-| Cline | — | JSON | Yes | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/cline-client.test.ts)) | — | Local listener only. Writes are coordinated through a lock file next to the config. |
-| Kilo Code | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-reasoning-controls.test.ts)) | — | The exporter also supports a remote listener (it adds the API key header). |
-| Factory Droid | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/droid-client.test.ts)) | — | Local listener only. [guide](/guides/factory-droid/) |
-| Gentle Shell | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/gentle-shell-client.test.ts)) | — | Local listener only. |
-| T3 Code | — | JSON | Yes | Anthropic Messages | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/t3code-client.test.ts)) | — | Local listener only. Apply runs a client-specific check first and can refuse. |
+| ZCode | — | JSON | Yes | Responses (curated) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/integrations-current-store.test.ts)) | — | Local listener only. Writes the client's current provider store. The client picks the endpoint from this setting (reviewed against the client's documented behavior). |
+| Command Code | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/command-code-client.test.ts)) | — | Local listener only. Writes are coordinated through a lock file next to the config. |
+| Prime | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/prime-client.test.ts)) | — | Local listener only. |
+| Aside | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | Local listener only. |
+| Raycast | — | YAML | Yes | Chat Completions (curated) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/raycast-client.test.ts)) | — | Local listener only. The client picks the endpoint from this setting (reviewed against the client's documented behavior). |
+| omo | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/omo-client.test.ts)) | — | Local listener only. |
+| Cline | — | JSON | Yes | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/cline-client.test.ts)) | — | Local listener only. Writes are coordinated through a lock file next to the config. |
+| Kilo Code | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-reasoning-controls.test.ts)) | — | The exporter also supports a remote listener (it adds the API key header). |
+| Factory Droid | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/droid-client.test.ts)) | — | Local listener only. [guide](/guides/factory-droid/) |
+| Gentle Shell | — | JSON | Yes | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/gentle-shell-client.test.ts)) | — | Local listener only. |
+| T3 Code | — | JSON | Yes | Anthropic Messages | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/t3code-client.test.ts)) | — | Local listener only. Apply runs a client-specific check first and can refuse. |
## Inbound endpoints
diff --git a/docs-site/src/content/docs/ru/guides/remote-hub.md b/docs-site/src/content/docs/ru/guides/remote-hub.md
index f463c3cc869..fda4a76d40b 100644
--- a/docs-site/src/content/docs/ru/guides/remote-hub.md
+++ b/docs-site/src/content/docs/ru/guides/remote-hub.md
@@ -161,7 +161,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/docs-site/src/content/docs/ru/reference/client-support.md b/docs-site/src/content/docs/ru/reference/client-support.md
index 95f1fcc881a..7c83a3564f6 100644
--- a/docs-site/src/content/docs/ru/reference/client-support.md
+++ b/docs-site/src/content/docs/ru/reference/client-support.md
@@ -18,34 +18,34 @@ opencodex — единый локальный шлюз для ваших ИИ-и
| Клиент | Нативно | Экспорт конфигурации | Управляемая интеграция файла | Входящий протокол | Уровень | Проверено в работе | Примечания |
| --- | --- | --- | --- | --- | --- | --- | --- |
-| Codex (CLI, app, SDK) | Да | — | — | Responses (проверено) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | Настраивается самим opencodex, без экспортируемого файла конфигурации. [руководство](/ru/guides/codex-integration/) |
-| Claude Code | Да | — | — | Anthropic Messages (проверено) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/claude-integration/claude-cli.test.ts)) | — | Настраивается самим opencodex, без экспортируемого файла конфигурации. [руководство](/ru/guides/claude-code/) |
+| Codex (CLI, app, SDK) | Да | — | — | Responses (проверено) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | Настраивается самим opencodex, без экспортируемого файла конфигурации. [руководство](/ru/guides/codex-integration/) |
+| Claude Code | Да | — | — | Anthropic Messages (проверено) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/claude-integration/claude-cli.test.ts)) | — | Настраивается самим opencodex, без экспортируемого файла конфигурации. [руководство](/ru/guides/claude-code/) |
| Claude Desktop | Да | — | — | Anthropic Messages (проверено) | implemented | — | Настраивается самим opencodex, без экспортируемого файла конфигурации. |
-| Grok Build | Да | — | — | Responses (проверено) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/providers/xai/grok-config-inject.test.ts)) | — | Настраивается самим opencodex, без экспортируемого файла конфигурации. [руководство](/ru/guides/grok-build/) |
-| Qoder | — | JSON | Да | Совместим с OpenAI (эндпоинт выбирает клиент) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/qoder-client.test.ts)) | — | Только локальный слушатель. |
+| Grok Build | Да | — | — | Responses (проверено) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/providers/xai/grok-config-inject.test.ts)) | — | Настраивается самим opencodex, без экспортируемого файла конфигурации. [руководство](/ru/guides/grok-build/) |
+| Qoder | — | JSON | Да | Совместим с OpenAI (эндпоинт выбирает клиент) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/qoder-client.test.ts)) | — | Только локальный слушатель. |
| Qoder CN | — | JSON | Да | Совместим с OpenAI (эндпоинт выбирает клиент) | implemented | — | Только локальный слушатель. |
-| WorkBuddy | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/agent-clients.test.ts)) | — | Только локальный слушатель. Перед применением выполняется проверка, специфичная для клиента, и возможен отказ. |
+| WorkBuddy | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/agent-clients.test.ts)) | — | Только локальный слушатель. Перед применением выполняется проверка, специфичная для клиента, и возможен отказ. |
| WorkBuddy AI | — | JSON | Да | Chat Completions | implemented | — | Только локальный слушатель. Перед применением выполняется проверка, специфичная для клиента, и возможен отказ. |
-| OpenCode | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Экспорт поддерживает и удалённого слушателя (добавляет заголовок API-ключа). [руководство](/ru/guides/opencode/) |
-| Pi | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Только локальный слушатель. [руководство](/ru/guides/pi/) |
-| Oh My Pi (omp) | — | YAML | Да | Chat Completions; Responses (только нативные модели OpenAI) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Только локальный слушатель. Изменяет только свой YAML-блок. |
-| Hermes | — | YAML | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/hermes-catalog-refresh.test.ts)) | — | Экспорт поддерживает и удалённого слушателя (добавляет заголовок API-ключа). Изменяет только свой YAML-блок. |
-| OpenClaw | — | JSON5 | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/gui/integrations-invariants.test.ts)) | — | Экспорт поддерживает и удалённого слушателя (добавляет заголовок API-ключа). |
-| Kimi CLI | — | TOML | Да | Совместим с OpenAI (эндпоинт выбирает клиент) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export-new-clients.test.ts)) | — | Только локальный слушатель. |
-| Gajae | — | YAML | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-modality-enum.test.ts)) | — | Только локальный слушатель. |
-| DSH | — | YAML | Да | Responses | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Только локальный слушатель. Пишет в текущее хранилище провайдеров клиента. Изменяет только свой YAML-блок. Запись согласуется через файл блокировки рядом с конфигурацией. |
+| OpenCode | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Экспорт поддерживает и удалённого слушателя (добавляет заголовок API-ключа). [руководство](/ru/guides/opencode/) |
+| Pi | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Только локальный слушатель. [руководство](/ru/guides/pi/) |
+| Oh My Pi (omp) | — | YAML | Да | Chat Completions; Responses (только нативные модели OpenAI) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Только локальный слушатель. Изменяет только свой YAML-блок. |
+| Hermes | — | YAML | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/hermes-catalog-refresh.test.ts)) | — | Экспорт поддерживает и удалённого слушателя (добавляет заголовок API-ключа). Изменяет только свой YAML-блок. |
+| OpenClaw | — | JSON5 | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/gui/integrations-invariants.test.ts)) | — | Экспорт поддерживает и удалённого слушателя (добавляет заголовок API-ключа). |
+| Kimi CLI | — | TOML | Да | Совместим с OpenAI (эндпоинт выбирает клиент) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export-new-clients.test.ts)) | — | Только локальный слушатель. |
+| Gajae | — | YAML | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-modality-enum.test.ts)) | — | Только локальный слушатель. |
+| DSH | — | YAML | Да | Responses | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Только локальный слушатель. Пишет в текущее хранилище провайдеров клиента. Изменяет только свой YAML-блок. Запись согласуется через файл блокировки рядом с конфигурацией. |
| MCode | — | YAML | Да | Anthropic Messages | implemented | — | Только локальный слушатель. Запись согласуется через файл блокировки рядом с конфигурацией. |
-| ZCode | — | JSON | Да | Responses (проверено) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/integrations-current-store.test.ts)) | — | Только локальный слушатель. Пишет в текущее хранилище провайдеров клиента. Клиент выбирает эндпоинт по этой настройке (проверено при ревью по документированному поведению клиента). |
-| Command Code | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/command-code-client.test.ts)) | — | Только локальный слушатель. Запись согласуется через файл блокировки рядом с конфигурацией. |
-| Prime | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/prime-client.test.ts)) | — | Только локальный слушатель. |
-| Aside | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | Только локальный слушатель. |
-| Raycast | — | YAML | Да | Chat Completions (проверено) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/raycast-client.test.ts)) | — | Только локальный слушатель. Клиент выбирает эндпоинт по этой настройке (проверено при ревью по документированному поведению клиента). |
-| omo | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/omo-client.test.ts)) | — | Только локальный слушатель. |
-| Cline | — | JSON | Да | Responses | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/cline-client.test.ts)) | — | Только локальный слушатель. Запись согласуется через файл блокировки рядом с конфигурацией. |
-| Kilo Code | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-reasoning-controls.test.ts)) | — | Экспорт поддерживает и удалённого слушателя (добавляет заголовок API-ключа). |
-| Factory Droid | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/droid-client.test.ts)) | — | Только локальный слушатель. [руководство](/ru/guides/factory-droid/) |
-| Gentle Shell | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/gentle-shell-client.test.ts)) | — | Только локальный слушатель. |
-| T3 Code | — | JSON | Да | Anthropic Messages | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/t3code-client.test.ts)) | — | Только локальный слушатель. Перед применением выполняется проверка, специфичная для клиента, и возможен отказ. |
+| ZCode | — | JSON | Да | Responses (проверено) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/integrations-current-store.test.ts)) | — | Только локальный слушатель. Пишет в текущее хранилище провайдеров клиента. Клиент выбирает эндпоинт по этой настройке (проверено при ревью по документированному поведению клиента). |
+| Command Code | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/command-code-client.test.ts)) | — | Только локальный слушатель. Запись согласуется через файл блокировки рядом с конфигурацией. |
+| Prime | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/prime-client.test.ts)) | — | Только локальный слушатель. |
+| Aside | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | Только локальный слушатель. |
+| Raycast | — | YAML | Да | Chat Completions (проверено) | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/raycast-client.test.ts)) | — | Только локальный слушатель. Клиент выбирает эндпоинт по этой настройке (проверено при ревью по документированному поведению клиента). |
+| omo | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/omo-client.test.ts)) | — | Только локальный слушатель. |
+| Cline | — | JSON | Да | Responses | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/cline-client.test.ts)) | — | Только локальный слушатель. Запись согласуется через файл блокировки рядом с конфигурацией. |
+| Kilo Code | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-reasoning-controls.test.ts)) | — | Экспорт поддерживает и удалённого слушателя (добавляет заголовок API-ключа). |
+| Factory Droid | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/droid-client.test.ts)) | — | Только локальный слушатель. [руководство](/ru/guides/factory-droid/) |
+| Gentle Shell | — | JSON | Да | Chat Completions | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/gentle-shell-client.test.ts)) | — | Только локальный слушатель. |
+| T3 Code | — | JSON | Да | Anthropic Messages | test-covered ([тест](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/t3code-client.test.ts)) | — | Только локальный слушатель. Перед применением выполняется проверка, специфичная для клиента, и возможен отказ. |
## Входящие эндпоинты
diff --git a/docs-site/src/content/docs/tr/contributing.md b/docs-site/src/content/docs/tr/contributing.md
index a7f7a10a47f..0601eab9bfd 100644
--- a/docs-site/src/content/docs/tr/contributing.md
+++ b/docs-site/src/content/docs/tr/contributing.md
@@ -104,12 +104,10 @@ commit'leri belirtin.
## Çekme istekleri
-- Hedef **`dev`** dalıdır. **`main`** dalına karşı özellik veya düzeltme çekme
- istekleri açmayın.
-- **`main`** yerine geçerli **`dev`** ucundan dallanın. Gerekli
- **`enforce-target`** denetimi, çekme isteği tabanının çok gerisinde kalırken
- birleştirme tabanı **`main`** ucunda oturan head'leri reddeder (#644'te
- görülen hata modu).
+- Hedef **`dev`** dalıdır ve aynı zamanda deponun varsayılan dalıdır.
+ **`main`** ve **`preview`**, tek dal modeli yürürlüğe girdiğinde silindi.
+ Gerekli **`enforce-target`** denetimi, tabanı **`dev`** dışında olan çekme
+ isteklerini reddeder (yığılmış alt PR'ler hariç).
- Gerçek bir açıklama yazın: Neyin neden değiştiğine dair bir **Özet** (Summary)
ve bir **Test planı** (veya eşdeğer içerik). Boş gövdeler, yalnızca yer tutucu
metinler ve gerçek satır sonları yerine kaçışlı `\n` kullanan açıklamalar
@@ -127,7 +125,7 @@ commit'leri belirtin.
## Proje bakımcıları
Mevcut bakımcılar, sorumlulukları ve inceleme ile birleştirme politikası
-[`MAINTAINERS.md`](https://github.com/lidge-jun/opencodex/blob/main/MAINTAINERS.md)
+[`MAINTAINERS.md`](https://github.com/lidge-jun/opencodex/blob/dev/MAINTAINERS.md)
dosyasında belgelenmiştir. Depo ve güvenliğe duyarlı yollar için GitHub inceleme
sahipliği `.github/CODEOWNERS` dosyasında bildirilmiştir.
diff --git a/docs-site/src/content/docs/tr/guides/remote-hub.md b/docs-site/src/content/docs/tr/guides/remote-hub.md
index 9ed0211773b..8ced721095e 100644
--- a/docs-site/src/content/docs/tr/guides/remote-hub.md
+++ b/docs-site/src/content/docs/tr/guides/remote-hub.md
@@ -161,7 +161,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/docs-site/src/content/docs/tr/reference/client-support.md b/docs-site/src/content/docs/tr/reference/client-support.md
index c70d2247739..4327afb2325 100644
--- a/docs-site/src/content/docs/tr/reference/client-support.md
+++ b/docs-site/src/content/docs/tr/reference/client-support.md
@@ -18,34 +18,34 @@ opencodex, yapay zekâ kodlama araçlarınız ve modelleriniz için tek bir yere
| İstemci | Yerel | Yapılandırma dışa aktarımı | Yönetilen dosya entegrasyonu | Gelen protokol | Destek düzeyi | Çalışırken doğrulandı | Notlar |
| --- | --- | --- | --- | --- | --- | --- | --- |
-| Codex (CLI, app, SDK) | Evet | — | — | Responses (incelendi) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | opencodex tarafından doğrudan kurulur; dışa aktarılan yapılandırma dosyası yoktur. [kılavuz](/tr/guides/codex-integration/) |
-| Claude Code | Evet | — | — | Anthropic Messages (incelendi) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/claude-integration/claude-cli.test.ts)) | — | opencodex tarafından doğrudan kurulur; dışa aktarılan yapılandırma dosyası yoktur. [kılavuz](/tr/guides/claude-code/) |
+| Codex (CLI, app, SDK) | Evet | — | — | Responses (incelendi) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | opencodex tarafından doğrudan kurulur; dışa aktarılan yapılandırma dosyası yoktur. [kılavuz](/tr/guides/codex-integration/) |
+| Claude Code | Evet | — | — | Anthropic Messages (incelendi) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/claude-integration/claude-cli.test.ts)) | — | opencodex tarafından doğrudan kurulur; dışa aktarılan yapılandırma dosyası yoktur. [kılavuz](/tr/guides/claude-code/) |
| Claude Desktop | Evet | — | — | Anthropic Messages (incelendi) | implemented | — | opencodex tarafından doğrudan kurulur; dışa aktarılan yapılandırma dosyası yoktur. |
-| Grok Build | Evet | — | — | Responses (incelendi) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/providers/xai/grok-config-inject.test.ts)) | — | opencodex tarafından doğrudan kurulur; dışa aktarılan yapılandırma dosyası yoktur. [kılavuz](/tr/guides/grok-build/) |
-| Qoder | — | JSON | Evet | OpenAI uyumlu (uç noktayı istemci seçer) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/qoder-client.test.ts)) | — | Yalnızca yerel dinleyici. |
+| Grok Build | Evet | — | — | Responses (incelendi) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/providers/xai/grok-config-inject.test.ts)) | — | opencodex tarafından doğrudan kurulur; dışa aktarılan yapılandırma dosyası yoktur. [kılavuz](/tr/guides/grok-build/) |
+| Qoder | — | JSON | Evet | OpenAI uyumlu (uç noktayı istemci seçer) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/qoder-client.test.ts)) | — | Yalnızca yerel dinleyici. |
| Qoder CN | — | JSON | Evet | OpenAI uyumlu (uç noktayı istemci seçer) | implemented | — | Yalnızca yerel dinleyici. |
-| WorkBuddy | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/agent-clients.test.ts)) | — | Yalnızca yerel dinleyici. Uygulamadan önce istemciye özgü bir denetim çalışır ve reddedebilir. |
+| WorkBuddy | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/agent-clients.test.ts)) | — | Yalnızca yerel dinleyici. Uygulamadan önce istemciye özgü bir denetim çalışır ve reddedebilir. |
| WorkBuddy AI | — | JSON | Evet | Chat Completions | implemented | — | Yalnızca yerel dinleyici. Uygulamadan önce istemciye özgü bir denetim çalışır ve reddedebilir. |
-| OpenCode | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Dışa aktarım uzak dinleyiciyi de destekler (API anahtarı başlığını ekler). [kılavuz](/tr/guides/opencode/) |
-| Pi | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Yalnızca yerel dinleyici. [kılavuz](/tr/guides/pi/) |
-| Oh My Pi (omp) | — | YAML | Evet | Chat Completions; Responses (yalnızca yerel OpenAI modelleri) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Yalnızca yerel dinleyici. Yalnızca kendi YAML bloğunu düzenler. |
-| Hermes | — | YAML | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/hermes-catalog-refresh.test.ts)) | — | Dışa aktarım uzak dinleyiciyi de destekler (API anahtarı başlığını ekler). Yalnızca kendi YAML bloğunu düzenler. |
-| OpenClaw | — | JSON5 | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/gui/integrations-invariants.test.ts)) | — | Dışa aktarım uzak dinleyiciyi de destekler (API anahtarı başlığını ekler). |
-| Kimi CLI | — | TOML | Evet | OpenAI uyumlu (uç noktayı istemci seçer) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export-new-clients.test.ts)) | — | Yalnızca yerel dinleyici. |
-| Gajae | — | YAML | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-modality-enum.test.ts)) | — | Yalnızca yerel dinleyici. |
-| DSH | — | YAML | Evet | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | Yalnızca yerel dinleyici. İstemcinin güncel sağlayıcı deposuna yazar. Yalnızca kendi YAML bloğunu düzenler. Yazmalar yapılandırmanın yanındaki bir kilit dosyasıyla eşgüdümlenir. |
+| OpenCode | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Dışa aktarım uzak dinleyiciyi de destekler (API anahtarı başlığını ekler). [kılavuz](/tr/guides/opencode/) |
+| Pi | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Yalnızca yerel dinleyici. [kılavuz](/tr/guides/pi/) |
+| Oh My Pi (omp) | — | YAML | Evet | Chat Completions; Responses (yalnızca yerel OpenAI modelleri) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Yalnızca yerel dinleyici. Yalnızca kendi YAML bloğunu düzenler. |
+| Hermes | — | YAML | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/hermes-catalog-refresh.test.ts)) | — | Dışa aktarım uzak dinleyiciyi de destekler (API anahtarı başlığını ekler). Yalnızca kendi YAML bloğunu düzenler. |
+| OpenClaw | — | JSON5 | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/gui/integrations-invariants.test.ts)) | — | Dışa aktarım uzak dinleyiciyi de destekler (API anahtarı başlığını ekler). |
+| Kimi CLI | — | TOML | Evet | OpenAI uyumlu (uç noktayı istemci seçer) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export-new-clients.test.ts)) | — | Yalnızca yerel dinleyici. |
+| Gajae | — | YAML | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-modality-enum.test.ts)) | — | Yalnızca yerel dinleyici. |
+| DSH | — | YAML | Evet | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | Yalnızca yerel dinleyici. İstemcinin güncel sağlayıcı deposuna yazar. Yalnızca kendi YAML bloğunu düzenler. Yazmalar yapılandırmanın yanındaki bir kilit dosyasıyla eşgüdümlenir. |
| MCode | — | YAML | Evet | Anthropic Messages | implemented | — | Yalnızca yerel dinleyici. Yazmalar yapılandırmanın yanındaki bir kilit dosyasıyla eşgüdümlenir. |
-| ZCode | — | JSON | Evet | Responses (incelendi) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/integrations-current-store.test.ts)) | — | Yalnızca yerel dinleyici. İstemcinin güncel sağlayıcı deposuna yazar. İstemci uç noktayı bu ayardan seçer (istemcinin belgelenmiş davranışına göre incelendi). |
-| Command Code | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/command-code-client.test.ts)) | — | Yalnızca yerel dinleyici. Yazmalar yapılandırmanın yanındaki bir kilit dosyasıyla eşgüdümlenir. |
-| Prime | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/prime-client.test.ts)) | — | Yalnızca yerel dinleyici. |
-| Aside | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | Yalnızca yerel dinleyici. |
-| Raycast | — | YAML | Evet | Chat Completions (incelendi) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/raycast-client.test.ts)) | — | Yalnızca yerel dinleyici. İstemci uç noktayı bu ayardan seçer (istemcinin belgelenmiş davranışına göre incelendi). |
-| omo | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/omo-client.test.ts)) | — | Yalnızca yerel dinleyici. |
-| Cline | — | JSON | Evet | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/cline-client.test.ts)) | — | Yalnızca yerel dinleyici. Yazmalar yapılandırmanın yanındaki bir kilit dosyasıyla eşgüdümlenir. |
-| Kilo Code | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-reasoning-controls.test.ts)) | — | Dışa aktarım uzak dinleyiciyi de destekler (API anahtarı başlığını ekler). |
-| Factory Droid | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/droid-client.test.ts)) | — | Yalnızca yerel dinleyici. [kılavuz](/tr/guides/factory-droid/) |
-| Gentle Shell | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/gentle-shell-client.test.ts)) | — | Yalnızca yerel dinleyici. |
-| T3 Code | — | JSON | Evet | Anthropic Messages | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/t3code-client.test.ts)) | — | Yalnızca yerel dinleyici. Uygulamadan önce istemciye özgü bir denetim çalışır ve reddedebilir. |
+| ZCode | — | JSON | Evet | Responses (incelendi) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/integrations-current-store.test.ts)) | — | Yalnızca yerel dinleyici. İstemcinin güncel sağlayıcı deposuna yazar. İstemci uç noktayı bu ayardan seçer (istemcinin belgelenmiş davranışına göre incelendi). |
+| Command Code | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/command-code-client.test.ts)) | — | Yalnızca yerel dinleyici. Yazmalar yapılandırmanın yanındaki bir kilit dosyasıyla eşgüdümlenir. |
+| Prime | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/prime-client.test.ts)) | — | Yalnızca yerel dinleyici. |
+| Aside | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | Yalnızca yerel dinleyici. |
+| Raycast | — | YAML | Evet | Chat Completions (incelendi) | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/raycast-client.test.ts)) | — | Yalnızca yerel dinleyici. İstemci uç noktayı bu ayardan seçer (istemcinin belgelenmiş davranışına göre incelendi). |
+| omo | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/omo-client.test.ts)) | — | Yalnızca yerel dinleyici. |
+| Cline | — | JSON | Evet | Responses | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/cline-client.test.ts)) | — | Yalnızca yerel dinleyici. Yazmalar yapılandırmanın yanındaki bir kilit dosyasıyla eşgüdümlenir. |
+| Kilo Code | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-reasoning-controls.test.ts)) | — | Dışa aktarım uzak dinleyiciyi de destekler (API anahtarı başlığını ekler). |
+| Factory Droid | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/droid-client.test.ts)) | — | Yalnızca yerel dinleyici. [kılavuz](/tr/guides/factory-droid/) |
+| Gentle Shell | — | JSON | Evet | Chat Completions | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/gentle-shell-client.test.ts)) | — | Yalnızca yerel dinleyici. |
+| T3 Code | — | JSON | Evet | Anthropic Messages | test-covered ([test](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/t3code-client.test.ts)) | — | Yalnızca yerel dinleyici. Uygulamadan önce istemciye özgü bir denetim çalışır ve reddedebilir. |
## Gelen uç noktalar
diff --git a/docs-site/src/content/docs/zh-cn/guides/remote-hub.md b/docs-site/src/content/docs/zh-cn/guides/remote-hub.md
index 083493bfcb8..7abc9f4f45e 100644
--- a/docs-site/src/content/docs/zh-cn/guides/remote-hub.md
+++ b/docs-site/src/content/docs/zh-cn/guides/remote-hub.md
@@ -155,7 +155,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/docs-site/src/content/docs/zh-cn/reference/client-support.md b/docs-site/src/content/docs/zh-cn/reference/client-support.md
index a757e151b7a..1101ad631b8 100644
--- a/docs-site/src/content/docs/zh-cn/reference/client-support.md
+++ b/docs-site/src/content/docs/zh-cn/reference/client-support.md
@@ -18,34 +18,34 @@ opencodex 是一个本地网关,连接你的 AI 编程工具与模型。部分
| 客户端 | 原生 | 配置导出 | 托管文件集成 | 入站协议 | 支持级别 | 运行验证 | 说明 |
| --- | --- | --- | --- | --- | --- | --- | --- |
-| Codex (CLI, app, SDK) | 是 | — | — | Responses (已审阅) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | 由 opencodex 直接配置,没有导出的配置文件。 [指南](/zh-cn/guides/codex-integration/) |
-| Claude Code | 是 | — | — | Anthropic Messages (已审阅) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/claude-integration/claude-cli.test.ts)) | — | 由 opencodex 直接配置,没有导出的配置文件。 [指南](/zh-cn/guides/claude-code/) |
+| Codex (CLI, app, SDK) | 是 | — | — | Responses (已审阅) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | 由 opencodex 直接配置,没有导出的配置文件。 [指南](/zh-cn/guides/codex-integration/) |
+| Claude Code | 是 | — | — | Anthropic Messages (已审阅) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/claude-integration/claude-cli.test.ts)) | — | 由 opencodex 直接配置,没有导出的配置文件。 [指南](/zh-cn/guides/claude-code/) |
| Claude Desktop | 是 | — | — | Anthropic Messages (已审阅) | implemented | — | 由 opencodex 直接配置,没有导出的配置文件。 |
-| Grok Build | 是 | — | — | Responses (已审阅) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/providers/xai/grok-config-inject.test.ts)) | — | 由 opencodex 直接配置,没有导出的配置文件。 [指南](/zh-cn/guides/grok-build/) |
-| Qoder | — | JSON | 是 | OpenAI 兼容(端点由客户端选择) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/qoder-client.test.ts)) | — | 仅限本地监听。 |
+| Grok Build | 是 | — | — | Responses (已审阅) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/providers/xai/grok-config-inject.test.ts)) | — | 由 opencodex 直接配置,没有导出的配置文件。 [指南](/zh-cn/guides/grok-build/) |
+| Qoder | — | JSON | 是 | OpenAI 兼容(端点由客户端选择) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/qoder-client.test.ts)) | — | 仅限本地监听。 |
| Qoder CN | — | JSON | 是 | OpenAI 兼容(端点由客户端选择) | implemented | — | 仅限本地监听。 |
-| WorkBuddy | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/agent-clients.test.ts)) | — | 仅限本地监听。应用前先运行针对该客户端的检查,可能拒绝。 |
+| WorkBuddy | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/agent-clients.test.ts)) | — | 仅限本地监听。应用前先运行针对该客户端的检查,可能拒绝。 |
| WorkBuddy AI | — | JSON | 是 | Chat Completions | implemented | — | 仅限本地监听。应用前先运行针对该客户端的检查,可能拒绝。 |
-| OpenCode | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 导出的配置也支持远程监听(会添加 API 密钥请求头)。 [指南](/zh-cn/guides/opencode/) |
-| Pi | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 仅限本地监听。 [指南](/zh-cn/guides/pi/) |
-| Oh My Pi (omp) | — | YAML | 是 | Chat Completions; Responses (仅原生 OpenAI 模型) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 仅限本地监听。只修改自己的 YAML 区块。 |
-| Hermes | — | YAML | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/hermes-catalog-refresh.test.ts)) | — | 导出的配置也支持远程监听(会添加 API 密钥请求头)。只修改自己的 YAML 区块。 |
-| OpenClaw | — | JSON5 | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/gui/integrations-invariants.test.ts)) | — | 导出的配置也支持远程监听(会添加 API 密钥请求头)。 |
-| Kimi CLI | — | TOML | 是 | OpenAI 兼容(端点由客户端选择) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export-new-clients.test.ts)) | — | 仅限本地监听。 |
-| Gajae | — | YAML | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-modality-enum.test.ts)) | — | 仅限本地监听。 |
-| DSH | — | YAML | 是 | Responses | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 仅限本地监听。写入客户端当前的提供商存储。只修改自己的 YAML 区块。通过配置文件旁的锁文件协调写入。 |
+| OpenCode | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 导出的配置也支持远程监听(会添加 API 密钥请求头)。 [指南](/zh-cn/guides/opencode/) |
+| Pi | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 仅限本地监听。 [指南](/zh-cn/guides/pi/) |
+| Oh My Pi (omp) | — | YAML | 是 | Chat Completions; Responses (仅原生 OpenAI 模型) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 仅限本地监听。只修改自己的 YAML 区块。 |
+| Hermes | — | YAML | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/hermes-catalog-refresh.test.ts)) | — | 导出的配置也支持远程监听(会添加 API 密钥请求头)。只修改自己的 YAML 区块。 |
+| OpenClaw | — | JSON5 | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/gui/integrations-invariants.test.ts)) | — | 导出的配置也支持远程监听(会添加 API 密钥请求头)。 |
+| Kimi CLI | — | TOML | 是 | OpenAI 兼容(端点由客户端选择) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export-new-clients.test.ts)) | — | 仅限本地监听。 |
+| Gajae | — | YAML | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-modality-enum.test.ts)) | — | 仅限本地监听。 |
+| DSH | — | YAML | 是 | Responses | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 仅限本地监听。写入客户端当前的提供商存储。只修改自己的 YAML 区块。通过配置文件旁的锁文件协调写入。 |
| MCode | — | YAML | 是 | Anthropic Messages | implemented | — | 仅限本地监听。通过配置文件旁的锁文件协调写入。 |
-| ZCode | — | JSON | 是 | Responses (已审阅) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/integrations-current-store.test.ts)) | — | 仅限本地监听。写入客户端当前的提供商存储。客户端根据此设置选择端点(已依据客户端的文档行为评审)。 |
-| Command Code | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/command-code-client.test.ts)) | — | 仅限本地监听。通过配置文件旁的锁文件协调写入。 |
-| Prime | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/prime-client.test.ts)) | — | 仅限本地监听。 |
-| Aside | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | 仅限本地监听。 |
-| Raycast | — | YAML | 是 | Chat Completions (已审阅) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/raycast-client.test.ts)) | — | 仅限本地监听。客户端根据此设置选择端点(已依据客户端的文档行为评审)。 |
-| omo | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/omo-client.test.ts)) | — | 仅限本地监听。 |
-| Cline | — | JSON | 是 | Responses | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/cline-client.test.ts)) | — | 仅限本地监听。通过配置文件旁的锁文件协调写入。 |
-| Kilo Code | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-reasoning-controls.test.ts)) | — | 导出的配置也支持远程监听(会添加 API 密钥请求头)。 |
-| Factory Droid | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/droid-client.test.ts)) | — | 仅限本地监听。 [指南](/zh-cn/guides/factory-droid/) |
-| Gentle Shell | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/gentle-shell-client.test.ts)) | — | 仅限本地监听。 |
-| T3 Code | — | JSON | 是 | Anthropic Messages | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/t3code-client.test.ts)) | — | 仅限本地监听。应用前先运行针对该客户端的检查,可能拒绝。 |
+| ZCode | — | JSON | 是 | Responses (已审阅) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/integrations-current-store.test.ts)) | — | 仅限本地监听。写入客户端当前的提供商存储。客户端根据此设置选择端点(已依据客户端的文档行为评审)。 |
+| Command Code | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/command-code-client.test.ts)) | — | 仅限本地监听。通过配置文件旁的锁文件协调写入。 |
+| Prime | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/prime-client.test.ts)) | — | 仅限本地监听。 |
+| Aside | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | 仅限本地监听。 |
+| Raycast | — | YAML | 是 | Chat Completions (已审阅) | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/raycast-client.test.ts)) | — | 仅限本地监听。客户端根据此设置选择端点(已依据客户端的文档行为评审)。 |
+| omo | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/omo-client.test.ts)) | — | 仅限本地监听。 |
+| Cline | — | JSON | 是 | Responses | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/cline-client.test.ts)) | — | 仅限本地监听。通过配置文件旁的锁文件协调写入。 |
+| Kilo Code | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-reasoning-controls.test.ts)) | — | 导出的配置也支持远程监听(会添加 API 密钥请求头)。 |
+| Factory Droid | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/droid-client.test.ts)) | — | 仅限本地监听。 [指南](/zh-cn/guides/factory-droid/) |
+| Gentle Shell | — | JSON | 是 | Chat Completions | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/gentle-shell-client.test.ts)) | — | 仅限本地监听。 |
+| T3 Code | — | JSON | 是 | Anthropic Messages | test-covered ([测试](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/t3code-client.test.ts)) | — | 仅限本地监听。应用前先运行针对该客户端的检查,可能拒绝。 |
## 入站端点
diff --git a/docs-site/src/content/docs/zh-tw/contributing.md b/docs-site/src/content/docs/zh-tw/contributing.md
index c40a66d739c..0eed0b6d114 100644
--- a/docs-site/src/content/docs/zh-tw/contributing.md
+++ b/docs-site/src/content/docs/zh-tw/contributing.md
@@ -66,10 +66,9 @@ cd docs-site && bun install && bun dev
## Pull request
-- 目標為 **`dev`**。請勿對 **`main`** 開啟功能或修復 pull request。
-- 從目前 **`dev`** tip 建立分支,而不是從 **`main`**。必填的 **`enforce-target`** 檢查會拒絕
- head merge base 位於 **`main`** tip 且分支遠落後於 pull request base 的請求(#644 中出現的
- 失敗模式)。
+- 目標為 **`dev`**,它也是 repository 的預設分支。**`main`** 與 **`preview`** 已隨單一分支
+ 模型上線而刪除。必填的 **`enforce-target`** 檢查會拒絕以 **`dev`** 以外分支為 base 的請求
+ (stacked 子 PR 除外)。
- 撰寫真實的描述:說明變更內容與原因的 **Summary**,加上 **Test plan**(或同等實質內容)。空的
內文、只有佔位符的文字,以及使用跳脫 `\n` 而非真實換行的描述都會無法通過檢查。
- 若 pull request 變更 `gui/` 下的檔案,請在描述中附上 UI 變更的螢幕截圖;`enforce-target` 會在
@@ -82,7 +81,7 @@ cd docs-site && bun install && bun dev
## 專案維護者
目前維護者、其職責,以及 review 與 merge 政策記錄在
-[`MAINTAINERS.md`](https://github.com/lidge-jun/opencodex/blob/main/MAINTAINERS.md)。repository 與
+[`MAINTAINERS.md`](https://github.com/lidge-jun/opencodex/blob/dev/MAINTAINERS.md)。repository 與
安全敏感路徑的 GitHub review 所有權宣告在 `.github/CODEOWNERS`。
## 約定
diff --git a/docs-site/src/content/docs/zh-tw/guides/remote-hub.md b/docs-site/src/content/docs/zh-tw/guides/remote-hub.md
index 50d3e9394a3..cde286eaed8 100644
--- a/docs-site/src/content/docs/zh-tw/guides/remote-hub.md
+++ b/docs-site/src/content/docs/zh-tw/guides/remote-hub.md
@@ -136,7 +136,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/docs-site/src/content/docs/zh-tw/reference/client-support.md b/docs-site/src/content/docs/zh-tw/reference/client-support.md
index 6439288f139..e7ba12a000c 100644
--- a/docs-site/src/content/docs/zh-tw/reference/client-support.md
+++ b/docs-site/src/content/docs/zh-tw/reference/client-support.md
@@ -18,34 +18,34 @@ opencodex 是一個本機閘道,連接你的 AI 程式開發工具與模型。
| 用戶端 | 原生 | 設定匯出 | 代管檔案整合 | 入站協定 | 支援等級 | 執行驗證 | 說明 |
| --- | --- | --- | --- | --- | --- | --- | --- |
-| Codex (CLI, app, SDK) | 是 | — | — | Responses (已審查) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | 由 opencodex 直接設定,沒有匯出的設定檔。 [指南](/zh-tw/guides/codex-integration/) |
-| Claude Code | 是 | — | — | Anthropic Messages (已審查) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/claude-integration/claude-cli.test.ts)) | — | 由 opencodex 直接設定,沒有匯出的設定檔。 [指南](/zh-tw/guides/claude-code/) |
+| Codex (CLI, app, SDK) | 是 | — | — | Responses (已審查) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/codex-integration/codex-inject-missing-config.test.ts)) | — | 由 opencodex 直接設定,沒有匯出的設定檔。 [指南](/zh-tw/guides/codex-integration/) |
+| Claude Code | 是 | — | — | Anthropic Messages (已審查) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/claude-integration/claude-cli.test.ts)) | — | 由 opencodex 直接設定,沒有匯出的設定檔。 [指南](/zh-tw/guides/claude-code/) |
| Claude Desktop | 是 | — | — | Anthropic Messages (已審查) | implemented | — | 由 opencodex 直接設定,沒有匯出的設定檔。 |
-| Grok Build | 是 | — | — | Responses (已審查) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/providers/xai/grok-config-inject.test.ts)) | — | 由 opencodex 直接設定,沒有匯出的設定檔。 [指南](/zh-tw/guides/grok-build/) |
-| Qoder | — | JSON | 是 | OpenAI 相容(端點由用戶端選擇) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/qoder-client.test.ts)) | — | 僅限本機監聽。 |
+| Grok Build | 是 | — | — | Responses (已審查) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/providers/xai/grok-config-inject.test.ts)) | — | 由 opencodex 直接設定,沒有匯出的設定檔。 [指南](/zh-tw/guides/grok-build/) |
+| Qoder | — | JSON | 是 | OpenAI 相容(端點由用戶端選擇) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/qoder-client.test.ts)) | — | 僅限本機監聽。 |
| Qoder CN | — | JSON | 是 | OpenAI 相容(端點由用戶端選擇) | implemented | — | 僅限本機監聽。 |
-| WorkBuddy | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/agent-clients.test.ts)) | — | 僅限本機監聽。套用前先執行該用戶端專屬的檢查,可能拒絕。 |
+| WorkBuddy | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/agent-clients.test.ts)) | — | 僅限本機監聽。套用前先執行該用戶端專屬的檢查,可能拒絕。 |
| WorkBuddy AI | — | JSON | 是 | Chat Completions | implemented | — | 僅限本機監聽。套用前先執行該用戶端專屬的檢查,可能拒絕。 |
-| OpenCode | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 匯出的設定也支援遠端監聽(會加入 API 金鑰標頭)。 [指南](/zh-tw/guides/opencode/) |
-| Pi | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 僅限本機監聽。 [指南](/zh-tw/guides/pi/) |
-| Oh My Pi (omp) | — | YAML | 是 | Chat Completions; Responses (僅原生 OpenAI 模型) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 僅限本機監聽。只修改自己的 YAML 區塊。 |
-| Hermes | — | YAML | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/hermes-catalog-refresh.test.ts)) | — | 匯出的設定也支援遠端監聽(會加入 API 金鑰標頭)。只修改自己的 YAML 區塊。 |
-| OpenClaw | — | JSON5 | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/gui/integrations-invariants.test.ts)) | — | 匯出的設定也支援遠端監聽(會加入 API 金鑰標頭)。 |
-| Kimi CLI | — | TOML | 是 | OpenAI 相容(端點由用戶端選擇) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export-new-clients.test.ts)) | — | 僅限本機監聽。 |
-| Gajae | — | YAML | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-modality-enum.test.ts)) | — | 僅限本機監聽。 |
-| DSH | — | YAML | 是 | Responses | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/config/client-config-export.test.ts)) | — | 僅限本機監聽。寫入用戶端目前的供應商儲存區。只修改自己的 YAML 區塊。透過設定檔旁的鎖定檔協調寫入。 |
+| OpenCode | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 匯出的設定也支援遠端監聽(會加入 API 金鑰標頭)。 [指南](/zh-tw/guides/opencode/) |
+| Pi | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 僅限本機監聽。 [指南](/zh-tw/guides/pi/) |
+| Oh My Pi (omp) | — | YAML | 是 | Chat Completions; Responses (僅原生 OpenAI 模型) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 僅限本機監聽。只修改自己的 YAML 區塊。 |
+| Hermes | — | YAML | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/hermes-catalog-refresh.test.ts)) | — | 匯出的設定也支援遠端監聽(會加入 API 金鑰標頭)。只修改自己的 YAML 區塊。 |
+| OpenClaw | — | JSON5 | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/gui/integrations-invariants.test.ts)) | — | 匯出的設定也支援遠端監聽(會加入 API 金鑰標頭)。 |
+| Kimi CLI | — | TOML | 是 | OpenAI 相容(端點由用戶端選擇) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export-new-clients.test.ts)) | — | 僅限本機監聽。 |
+| Gajae | — | YAML | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-modality-enum.test.ts)) | — | 僅限本機監聽。 |
+| DSH | — | YAML | 是 | Responses | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/config/client-config-export.test.ts)) | — | 僅限本機監聽。寫入用戶端目前的供應商儲存區。只修改自己的 YAML 區塊。透過設定檔旁的鎖定檔協調寫入。 |
| MCode | — | YAML | 是 | Anthropic Messages | implemented | — | 僅限本機監聽。透過設定檔旁的鎖定檔協調寫入。 |
-| ZCode | — | JSON | 是 | Responses (已審查) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/integrations-current-store.test.ts)) | — | 僅限本機監聽。寫入用戶端目前的供應商儲存區。用戶端依此設定選擇端點(已依用戶端的文件行為審查)。 |
-| Command Code | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/command-code-client.test.ts)) | — | 僅限本機監聽。透過設定檔旁的鎖定檔協調寫入。 |
-| Prime | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/prime-client.test.ts)) | — | 僅限本機監聽。 |
-| Aside | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | 僅限本機監聽。 |
-| Raycast | — | YAML | 是 | Chat Completions (已審查) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/raycast-client.test.ts)) | — | 僅限本機監聽。用戶端依此設定選擇端點(已依用戶端的文件行為審查)。 |
-| omo | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/omo-client.test.ts)) | — | 僅限本機監聽。 |
-| Cline | — | JSON | 是 | Responses | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/cline-client.test.ts)) | — | 僅限本機監聽。透過設定檔旁的鎖定檔協調寫入。 |
-| Kilo Code | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/client-export-reasoning-controls.test.ts)) | — | 匯出的設定也支援遠端監聽(會加入 API 金鑰標頭)。 |
-| Factory Droid | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/droid-client.test.ts)) | — | 僅限本機監聽。 [指南](/zh-tw/guides/factory-droid/) |
-| Gentle Shell | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/gentle-shell-client.test.ts)) | — | 僅限本機監聽。 |
-| T3 Code | — | JSON | 是 | Anthropic Messages | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/main/tests/clients/t3code-client.test.ts)) | — | 僅限本機監聽。套用前先執行該用戶端專屬的檢查,可能拒絕。 |
+| ZCode | — | JSON | 是 | Responses (已審查) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/integrations-current-store.test.ts)) | — | 僅限本機監聽。寫入用戶端目前的供應商儲存區。用戶端依此設定選擇端點(已依用戶端的文件行為審查)。 |
+| Command Code | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/command-code-client.test.ts)) | — | 僅限本機監聽。透過設定檔旁的鎖定檔協調寫入。 |
+| Prime | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/prime-client.test.ts)) | — | 僅限本機監聽。 |
+| Aside | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/aside-profiles-catalog-refresh.test.ts)) | — | 僅限本機監聽。 |
+| Raycast | — | YAML | 是 | Chat Completions (已審查) | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/raycast-client.test.ts)) | — | 僅限本機監聽。用戶端依此設定選擇端點(已依用戶端的文件行為審查)。 |
+| omo | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/omo-client.test.ts)) | — | 僅限本機監聽。 |
+| Cline | — | JSON | 是 | Responses | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/cline-client.test.ts)) | — | 僅限本機監聽。透過設定檔旁的鎖定檔協調寫入。 |
+| Kilo Code | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/client-export-reasoning-controls.test.ts)) | — | 匯出的設定也支援遠端監聽(會加入 API 金鑰標頭)。 |
+| Factory Droid | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/droid-client.test.ts)) | — | 僅限本機監聽。 [指南](/zh-tw/guides/factory-droid/) |
+| Gentle Shell | — | JSON | 是 | Chat Completions | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/gentle-shell-client.test.ts)) | — | 僅限本機監聽。 |
+| T3 Code | — | JSON | 是 | Anthropic Messages | test-covered ([測試](https://github.com/lidge-jun/opencodex/blob/dev/tests/clients/t3code-client.test.ts)) | — | 僅限本機監聽。套用前先執行該用戶端專屬的檢查,可能拒絕。 |
## 入站端點
diff --git a/readme/README.fr.md b/readme/README.fr.md
index c68481e86e0..1a6820fbd91 100644
--- a/readme/README.fr.md
+++ b/readme/README.fr.md
@@ -10,7 +10,7 @@
-
+
@@ -202,7 +202,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/readme/README.ja.md b/readme/README.ja.md
index 0bdb4d1532f..734f849f17d 100644
--- a/readme/README.ja.md
+++ b/readme/README.ja.md
@@ -10,7 +10,7 @@
-
+
@@ -200,7 +200,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/readme/README.ko.md b/readme/README.ko.md
index 8fea3df4aac..6586139d130 100644
--- a/readme/README.ko.md
+++ b/readme/README.ko.md
@@ -10,7 +10,7 @@
-
+
@@ -196,7 +196,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/readme/README.ru.md b/readme/README.ru.md
index 68c350f86b5..0b1d8184243 100644
--- a/readme/README.ru.md
+++ b/readme/README.ru.md
@@ -10,7 +10,7 @@
-
+
@@ -205,7 +205,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/readme/README.tr.md b/readme/README.tr.md
index 47dc2956118..8bb58c01bcd 100644
--- a/readme/README.tr.md
+++ b/readme/README.tr.md
@@ -10,7 +10,7 @@
-
+
@@ -202,7 +202,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/readme/README.zh-CN.md b/readme/README.zh-CN.md
index f3bd90b0b26..1c0a6ef79b6 100644
--- a/readme/README.zh-CN.md
+++ b/readme/README.zh-CN.md
@@ -10,7 +10,7 @@
-
+
@@ -196,7 +196,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/readme/README.zh-TW.md b/readme/README.zh-TW.md
index 69efde4b541..b48d492e0d5 100644
--- a/readme/README.zh-TW.md
+++ b/readme/README.zh-TW.md
@@ -10,7 +10,7 @@
-
+
@@ -196,7 +196,7 @@ services:
hub:
pull_policy: build
build:
- context: https://github.com/lidge-jun/opencodex.git#main
+ context: https://github.com/lidge-jun/opencodex.git#dev
dockerfile: Dockerfile
target: runtime
args:
diff --git a/readme/i18n-manifest.json b/readme/i18n-manifest.json
index 6e523ba886a..7fc9221d996 100644
--- a/readme/i18n-manifest.json
+++ b/readme/i18n-manifest.json
@@ -6,43 +6,43 @@
"file": "readme/README.fr.md",
"label": "Français",
"docsPath": "fr",
- "sourceSha256": "b7ae125b66e98f33611b6b9cd581c7759ce47b773df834572c86d8ee3c95e4a7"
+ "sourceSha256": "317fdcc0b4e903303817e820afd6fd620dccbcee9ab0caf9e64fd87e9a966682"
},
"ko": {
"file": "readme/README.ko.md",
"label": "한국어",
"docsPath": "ko",
- "sourceSha256": "b7ae125b66e98f33611b6b9cd581c7759ce47b773df834572c86d8ee3c95e4a7"
+ "sourceSha256": "317fdcc0b4e903303817e820afd6fd620dccbcee9ab0caf9e64fd87e9a966682"
},
"zh-CN": {
"file": "readme/README.zh-CN.md",
"label": "简体中文",
"docsPath": "zh-cn",
- "sourceSha256": "b7ae125b66e98f33611b6b9cd581c7759ce47b773df834572c86d8ee3c95e4a7"
+ "sourceSha256": "317fdcc0b4e903303817e820afd6fd620dccbcee9ab0caf9e64fd87e9a966682"
},
"zh-TW": {
"file": "readme/README.zh-TW.md",
"label": "繁體中文",
"docsPath": "zh-tw",
- "sourceSha256": "b7ae125b66e98f33611b6b9cd581c7759ce47b773df834572c86d8ee3c95e4a7"
+ "sourceSha256": "317fdcc0b4e903303817e820afd6fd620dccbcee9ab0caf9e64fd87e9a966682"
},
"ru": {
"file": "readme/README.ru.md",
"label": "Русский",
"docsPath": "ru",
- "sourceSha256": "b7ae125b66e98f33611b6b9cd581c7759ce47b773df834572c86d8ee3c95e4a7"
+ "sourceSha256": "317fdcc0b4e903303817e820afd6fd620dccbcee9ab0caf9e64fd87e9a966682"
},
"ja": {
"file": "readme/README.ja.md",
"label": "日本語",
"docsPath": "ja",
- "sourceSha256": "b7ae125b66e98f33611b6b9cd581c7759ce47b773df834572c86d8ee3c95e4a7"
+ "sourceSha256": "317fdcc0b4e903303817e820afd6fd620dccbcee9ab0caf9e64fd87e9a966682"
},
"tr": {
"file": "readme/README.tr.md",
"label": "Türkçe",
"docsPath": "tr",
- "sourceSha256": "b7ae125b66e98f33611b6b9cd581c7759ce47b773df834572c86d8ee3c95e4a7"
+ "sourceSha256": "317fdcc0b4e903303817e820afd6fd620dccbcee9ab0caf9e64fd87e9a966682"
}
}
}
diff --git a/scripts/bump-dev-version.ts b/scripts/bump-dev-version.ts
index 7dff79d1530..d36c733e139 100644
--- a/scripts/bump-dev-version.ts
+++ b/scripts/bump-dev-version.ts
@@ -4,12 +4,11 @@
*
* WHY THIS EXISTS
*
- * `scripts/release.ts` runs only on `main` or `preview` (`allowedBranches`), bumps
- * `package.json` there, and pushes that branch. `release.yml` ends at "Create GitHub
- * release". Nothing advances `dev`. So the moment a release publishes, `dev` carries a
- * version that is at or behind a published one, and
- * `tests/ci-workflows/release-version-line.test.ts` fails on `dev` and on every pull request opened
- * against it — inherited red that a contributor cannot fix from their own diff.
+ * The former branch-based release flow advanced a release branch without advancing
+ * `dev`, leaving its planned version at or behind the published version. The current
+ * release flow builds from a green `dev` commit and stamps the version in each build;
+ * it does not require a committed pre-move. This helper remains available for an
+ * explicit maintainer-controlled version adjustment.
*
* That has been repaired by hand four times: `32529c2b2`, `e4a85d134`, `076ad3036`,
* `befcac3e1`. The second of those ADDED the detector, and two more repairs followed
@@ -20,8 +19,8 @@
* This decides a version. It does no git and no network work, which is what makes it
* unit-testable and what keeps the credential surface in the workflow that calls it.
* It does not merge anything: `.github/workflows/dev-version-bump.yml` uses the
- * output to open a pull request, and a human still merges that. Until they do, the
- * red persists. This is a prepared repair, not an automatic one.
+ * output to open a pull request, and a human still merges that. This is a prepared
+ * adjustment, not an automatic release step.
*
* THE RULE
*
diff --git a/scripts/doctor-gui-if-changed.ts b/scripts/doctor-gui-if-changed.ts
index dbef9c28760..9f4232834d7 100644
--- a/scripts/doctor-gui-if-changed.ts
+++ b/scripts/doctor-gui-if-changed.ts
@@ -1,5 +1,5 @@
/**
- * Run React Doctor in gui/ when this push includes gui/ changes.
+ * Run React Doctor in gui/ when this change set includes gui/ changes.
* Used by `bun run prepush`.
*
* Gating by contract (doctor.config.json blocking: "warning"): findings fail
@@ -81,8 +81,8 @@ if (import.meta.main) {
} else {
let range: string | null = null;
if (hasRef("@{u}")) range = "@{u}...HEAD";
- else if (hasRef("origin/main")) range = "origin/main...HEAD";
- else if (hasRef("main")) range = "main...HEAD";
+ else if (hasRef("origin/dev")) range = "origin/dev...HEAD";
+ else if (hasRef("dev")) range = "dev...HEAD";
hadBase = range !== null;
files = range ? diffNames(range) : [];
}
diff --git a/scripts/generate-client-support-matrix.ts b/scripts/generate-client-support-matrix.ts
index dc98b8fa416..c78f8f988b5 100644
--- a/scripts/generate-client-support-matrix.ts
+++ b/scripts/generate-client-support-matrix.ts
@@ -34,7 +34,7 @@ export const NATIVE_ROSTER_FILE = "src/server/management/native-integration-rout
export const RUNTIME_RESULTS_FILE = "scripts/client-support-matrix/runtime-verified.json";
const PAGE = "reference/client-support.md";
const OWNER = "GENERATED by scripts/generate-client-support-matrix.ts";
-const REPO_BLOB = "https://github.com/lidge-jun/opencodex/blob/main/";
+const REPO_BLOB = "https://github.com/lidge-jun/opencodex/blob/dev/";
const REPO_ROOT = join(import.meta.dir, "..");
const PROTOCOL_NAMES: Record, string> = {
diff --git a/scripts/lint-gui-if-changed.ts b/scripts/lint-gui-if-changed.ts
index fd504489ac1..7acdd113f83 100644
--- a/scripts/lint-gui-if-changed.ts
+++ b/scripts/lint-gui-if-changed.ts
@@ -58,8 +58,8 @@ if (import.meta.main) {
} else {
let range: string | null = null;
if (hasRef("@{u}")) range = "@{u}...HEAD";
- else if (hasRef("origin/main")) range = "origin/main...HEAD";
- else if (hasRef("main")) range = "main...HEAD";
+ else if (hasRef("origin/dev")) range = "origin/dev...HEAD";
+ else if (hasRef("dev")) range = "dev...HEAD";
hadBase = range !== null;
files = range ? diffNames(range) : [];
}
diff --git a/scripts/release-version-sources.ts b/scripts/release-version-sources.ts
index eb83059139f..c902f0e5b4a 100644
--- a/scripts/release-version-sources.ts
+++ b/scripts/release-version-sources.ts
@@ -8,18 +8,17 @@
* takes it from `desktop/src-tauri/tauri.conf.json`, the Rust crate from
* `desktop/src-tauri/Cargo.toml` (mirrored in the `opencodex-desktop` entry of
* `desktop/src-tauri/Cargo.lock`), and `desktop/scripts/build-widget.sh` stamps the
- * widget plist from `tauri.conf.json`. The release workflow injects no version into the
- * desktop build, while the updater manifest is derived from the dispatch input.
+ * widget plist from `tauri.conf.json`. The release workflow stamps and checks the
+ * selected version in the build checkouts before packaging.
*
* So when only `package.json` moves, a release ships an app that reports the previous version
* under a manifest naming the new one. The desktop updater then keeps offering the same release,
* because the installed app never reports that it caught up. `dev` reached exactly that state
* when `package.json` moved to 2.62.0 and the three desktop sources stayed at 2.61.0.
*
- * Every path that moves the version goes through here: `scripts/bump-dev-version.ts` for the
- * `dev` pre-move, `scripts/release.ts` for the release commit on `main`/`preview`, and
- * `.github/workflows/release.yml` / `.github/workflows/dev-version-bump.yml`, which run
- * `check` before they build or open a pull request.
+ * Release builds use this helper to sync and check their four version sources.
+ * The maintainer-controlled `dev-version-bump.yml` workflow also uses it when
+ * preparing an optional version adjustment pull request.
*
* Usage:
* bun scripts/release-version-sources.ts check [] [--root ]
diff --git a/structure/desktop-shell.md b/structure/desktop-shell.md
index a6ccebd48fc..3cb595286a7 100644
--- a/structure/desktop-shell.md
+++ b/structure/desktop-shell.md
@@ -380,8 +380,8 @@ The lane takes about 15 minutes, so a pull request selects it only through the `
(`scripts/build-standalone.ts`, `scripts/standalone-targets.ts`, `src/lib/standalone.ts`,
`src/lib/bun-runtime.ts`), native keyring staging (`scripts/standalone-keyring.ts`,
`src/lib/keyring-native.ts`), `package.json`, `bun.lock` and `ci.yml` itself. Ordinary `src/**` and
-`gui/**` edits do not run it on a pull request; promotion pushes to `main` and `preview` and
-`workflow_dispatch` always do, so a packaging regression from such an edit surfaces at promotion.
+`gui/**` edits do not run it on a pull request; a manual `workflow_dispatch` on `dev` always does,
+so a packaging regression from such an edit surfaces in the batched full run.
Extraction is intentional. A GitHub-hosted runner is disposable but its package database is still a
shared job resource, and a normal pull request does not need passwordless package installation or GUI
diff --git a/structure/ops/docs-and-release.md b/structure/ops/docs-and-release.md
index 2e5ade6ecaa..5a273bb500d 100644
--- a/structure/ops/docs-and-release.md
+++ b/structure/ops/docs-and-release.md
@@ -137,14 +137,14 @@ commit SHA before checkout. The build has read-only contents access; only the de
Pages and OIDC write permissions. There are no push triggers. The scoped `docs-site-build` PR
job validates the site before merge, including the internal-link integration.
-Before cutover, a maintainer must configure Pages to use GitHub Actions and restrict the
-`github-pages` environment to the protected `dev` branch, with required reviewers according to
-repository policy. Do not allow arbitrary branches or tags in that environment: a branch-selected
-workflow can replace its own guards. Protect `dev` and release tags, and verify these settings
-before deploying. Changing the repository default branch from `main` to `dev` is a separate
-maintainer-controlled operation; until then default-branch automation still loads from `main`.
-The legacy `main` and `preview` branches are retained for recovery and migration. No repository
-setting change or production deploy is implied by this documentation.
+A maintainer configures Pages to use GitHub Actions and restricts the `github-pages`
+environment to the protected `dev` branch, with required reviewers according to repository
+policy. Do not allow arbitrary branches or tags in that environment: a branch-selected workflow
+can replace its own guards. Protect `dev` and release tags, and verify these settings before
+deploying. The repository default branch is `dev`, so default-branch automation loads from it.
+The legacy `main` and `preview` branches were deleted once the single-branch model was in place;
+released history remains reachable through tags. No repository setting change or production
+deploy is implied by this documentation.
Service lifecycle evidence includes the legacy CLI entrypoint `src/cli.ts` as well as the
service implementation and desktop packaging paths.
@@ -225,15 +225,15 @@ cannot supply a write-job PR number. If no unique local current-head candidate r
| `.github/workflows/deploy-docs.yml` | Manual dispatch from `dev` | Builds a published stable release at its resolved commit and deploys to Pages; the PR build gate is `docs-site-build`. |
| `.github/workflows/service-lifecycle.yml` | Filtered pull requests and manual dispatch | Linux, macOS and Windows service checks; manual dispatch validates an exact `dev` ancestor source SHA. |
| `.github/workflows/catalog-async-contracts.yml` | Filtered pull requests and manual dispatch | Read-only catalog contracts; PRs run Ubuntu and manual dispatch from `dev` runs all three platforms. |
-| `.github/workflows/enforce-pr-target.yml` | `pull_request_target` (opened, reopened, edited, labeled, unlabeled, ready_for_review, synchronize) plus default-branch `status` events filtered to successful `CodeRabbit` statuses | The `enforce-target` gate: rejects pull requests whose head ancestry sits on the `main` tip while far behind `dev`, rejects empty or malformed descriptions, requires a GUI screenshot when the title/body mentions `gui` (immediately waivable with the maintainer-controlled `gui-screenshot-waived` label; legacy maintainer comments remain compatibility evidence on later PR events), keeps contributor PRs in draft until a four-box readiness checklist is complete, verifies the CI / latest-dev / Codex+CodeRabbit-findings claims (review threads plus current-head CodeRabbit review-body findings outside the diff range), and adds a `review-ready` status label at the ready moment. CodeRabbit status SHAs must resolve to exactly one open current-head PR before writes. Stacked child PRs targeting another open PR's head skip the wrong-base gate. `labeled`/`unlabeled` wake the gate only for `gui-screenshot-waived` and the `HYGIENE_GATE_LABELS` exported by `.github/scripts/pr-hygiene.cjs`; `tests/ci-workflows/ci-workflows.test.ts` pins the two lists together. Head-specific exception labels (`test-exception-approved`, `suppression-approved`, `generated-change-approved`, `dependency-change-approved`, `attribution-approved`) count only while the head and head-rewrite count that `pr-hygiene.yml` last recorded in its comment section are unchanged; both gates read that record and only the hygiene workflow writes it or removes the labels. |
+| `.github/workflows/enforce-pr-target.yml` | `pull_request_target` (opened, reopened, edited, labeled, unlabeled, ready_for_review, synchronize) plus default-branch `status` events filtered to successful `CodeRabbit` statuses | The `enforce-target` gate: rejects pull requests whose base is not `dev` (stacked children excepted), rejects empty or malformed descriptions, requires a GUI screenshot when the title/body mentions `gui` (immediately waivable with the maintainer-controlled `gui-screenshot-waived` label; legacy maintainer comments remain compatibility evidence on later PR events), keeps contributor PRs in draft until a four-box readiness checklist is complete, verifies the CI / latest-dev / Codex+CodeRabbit-findings claims (review threads plus current-head CodeRabbit review-body findings outside the diff range), and adds a `review-ready` status label at the ready moment. CodeRabbit status SHAs must resolve to exactly one open current-head PR before writes. Stacked child PRs targeting another open PR's head skip the wrong-base gate. `labeled`/`unlabeled` wake the gate only for `gui-screenshot-waived` and the `HYGIENE_GATE_LABELS` exported by `.github/scripts/pr-hygiene.cjs`; `tests/ci-workflows/ci-workflows.test.ts` pins the two lists together. Head-specific exception labels (`test-exception-approved`, `suppression-approved`, `generated-change-approved`, `dependency-change-approved`, `attribution-approved`) count only while the head and head-rewrite count that `pr-hygiene.yml` last recorded in its comment section are unchanged; both gates read that record and only the hygiene workflow writes it or removes the labels. |
| `.github/workflows/enforce-issue-quality.yml` | `issues` (opened, edited, reopened), `issue_comment` (created, edited), or manual dispatch with an issue number | Issue-template compliance gate. |
-| `.github/workflows/issue-quality-tests.yml` | `pull_request` and `push` to `main`/`preview` filtered on the issue/PR automation scripts, templates, and their workflows | Tests the issue and PR automation scripts themselves, so the gates cannot rot silently. |
+| `.github/workflows/issue-quality-tests.yml` | `pull_request` filtered on the issue/PR automation scripts, templates, and their workflows | Tests the issue and PR automation scripts themselves, so the gates cannot rot silently. |
| `.github/workflows/issue-triage.yml` | `issues` (opened) | Duplicate detection and triage labeling for new issues. |
| `.github/workflows/pr-labeler.yml` | `pull_request_target` (opened, edited, synchronize, labeled, unlabeled) | Type and path labeling plus title sync; `labeled`/`unlabeled` let a human override enqueue a fresher run in the per-PR concurrency group. |
-| `.github/workflows/react-doctor.yml` | `pull_request` (opened, synchronize, reopened, ready_for_review) touching `gui/**` or the workflow, and every `push` to `main` | React-focused static review. Findings fail the job; write-scoped outputs stay disabled, a contract pinned by `tests/ci-workflows/ci-workflows.test.ts`. |
+| `.github/workflows/react-doctor.yml` | `pull_request` (opened, synchronize, reopened, ready_for_review) touching `gui/**` or the workflow | React-focused static review. Findings fail the job; write-scoped outputs stay disabled, a contract pinned by `tests/ci-workflows/ci-workflows.test.ts`. |
| `.github/workflows/stale-needs-info.yml` | `schedule` only (daily 06:15 UTC); deliberately no manual dispatch | Closes issues left in needs-info past the grace period. Manual dispatch is omitted so a branch-selected run cannot execute that branch's body with issue write scope. |
-`pull_request_target`, `issues`, and `schedule` workflows load from the repository default branch. Until a maintainer changes the default to `dev`, landing a change on `dev` alone does not change their live behavior.
+`pull_request_target`, `issues`, and `schedule` workflows load from the repository default branch, which is `dev`.
CI setup uses the [Bun runtime and test-runner pins](../runtime.md#bun-runtime-and-test-runner): test jobs (including development-version validation) choose `test-runner`, while release packaging, desktop/widget compilation and runtime smokes keep the default `runtime` role. Local layout verification resolves that test pin, and `gui/package.json` runs `scripts/test-with-pinned-bun.ts` to preserve its working directory, configuration and arguments on the same pin. The wrapper forwards SIGINT, SIGTERM and SIGHUP, waits for child exit and preserves interruption status (130, 143 or 129).
@@ -298,10 +298,11 @@ changed source area even when no text edit is needed.
[`AGENTS.md`](../../AGENTS.md) and [`MAINTAINERS.md`](../../MAINTAINERS.md) are authoritative; this section
exists so the repository-shape source of truth does not omit the shape of its own history.
-- `dev` is the single integration and release-source branch. `main` and `preview` remain protected
- historical branches for migration and recovery. One documented
- exception: a stacked child PR may target another **open** PR's head branch as a review workflow, and
- is retargeted to `dev` once the parent lands or closes.
+- `dev` is the single integration and release-source branch and the repository default branch.
+ `main` and `preview` were deleted after the single-branch model was in place; released history
+ remains reachable through tags. One documented exception: a stacked child PR may target another
+ **open** PR's head branch as a review workflow, and is retargeted to `dev` once the parent lands
+ or closes.
- Bun-native TypeScript on `dev` is the only runtime line. The former Go native-runtime experiment is
retired and archived, and no `go/` tree is tracked in this repository; a local `go/` directory is
untracked leftovers. If native code returns, the expectation is an incremental module landing on
@@ -329,7 +330,7 @@ enforcement. For `dev`, a current maintainer with live `maintain` or `admin` acc
explicitly integrate a PR without a second maintainer approval. The optional merge-review
helper validates this actor/base exception separately from its default contributor-approval
path; it does not certify CI or security review. The PR-only bypass leaves direct pushes,
-force-pushes and deletion blocked. `main` and `preview` retain their existing review rules.
+force-pushes and deletion blocked.
A new dashboard management operation ships with its `ocx` command in the same change, declared in
`src/cli/capabilities.ts`, or with an explicit note that it is visual-only (theme, language,
diff --git a/tests/ci-workflows/ci-concurrency-groups.test.ts b/tests/ci-workflows/ci-concurrency-groups.test.ts
index 69c1c4fb583..51d96c15653 100644
--- a/tests/ci-workflows/ci-concurrency-groups.test.ts
+++ b/tests/ci-workflows/ci-concurrency-groups.test.ts
@@ -147,10 +147,10 @@ test("the evaluator refuses an expression it does not model", () => {
expect(() => render("${{ startsWith(github.ref, 'refs/tags/') }}", push("1"))).toThrow(/unsupported expression term/);
});
-test("scheduled runs on main never share the push group or cancel earlier runs", () => {
- const scheduled = (run_id: string): GithubContext => ({ event_name: "schedule", ref: "refs/heads/main", run_id });
- const mainPush: GithubContext = { event_name: "push", ref: "refs/heads/main", run_id: "3" };
- expect(concurrency(scheduled("1")).group).not.toBe(concurrency(mainPush).group);
+test("scheduled runs never share the push group or cancel earlier runs", () => {
+ const scheduled = (run_id: string): GithubContext => ({ event_name: "schedule", ref: "refs/heads/dev", run_id });
+ const devPush: GithubContext = { event_name: "push", ref: "refs/heads/dev", run_id: "3" };
+ expect(concurrency(scheduled("1")).group).not.toBe(concurrency(devPush).group);
expect(concurrency(scheduled("1")).group).not.toBe(concurrency(scheduled("2")).group);
expect(concurrency(scheduled("1")).cancels).toBe("false");
});
diff --git a/tests/ci-workflows/ci-pr-hygiene-approvals.test.ts b/tests/ci-workflows/ci-pr-hygiene-approvals.test.ts
index 897a9272af6..9191e904557 100644
--- a/tests/ci-workflows/ci-pr-hygiene-approvals.test.ts
+++ b/tests/ci-workflows/ci-pr-hygiene-approvals.test.ts
@@ -327,7 +327,7 @@ describe("pr-hygiene head-bound approvals", () => {
// 2. The gate runs with the approval applied: it creates its own comment,
// leaves the standalone one alone, and keeps the suppression failure.
const gateRun = await runEnforcePrTarget(
- workflowScript("enforce-pr-target.yml", "enforce-target", "Enforce PR target, ancestry, and description"),
+ workflowScript("enforce-pr-target.yml", "enforce-target", "Enforce PR target and description"),
{
pr: { base: { ref: "dev" }, draft: true },
labels: ["suppression-approved"],
@@ -462,7 +462,7 @@ describe("pr-hygiene head-bound approvals", () => {
});
describe("enforce gate reads the hygiene head binding", () => {
- const gateScript = () => workflowScript("enforce-pr-target.yml", "enforce-target", "Enforce PR target, ancestry, and description");
+ const gateScript = () => workflowScript("enforce-pr-target.yml", "enforce-target", "Enforce PR target and description");
async function gate(options: { labels: string[]; record?: string; failOn?: string[]; issueEvents?: Array<{ event: string }> }) {
return runEnforcePrTarget(gateScript(), {
pr: { base: { ref: "dev" }, draft: true },
@@ -518,7 +518,7 @@ describe("enforce gate reads the hygiene head binding", () => {
});
describe("approval record survives comment rewrites", () => {
- const gateScript = () => workflowScript("enforce-pr-target.yml", "enforce-target", "Enforce PR target, ancestry, and description");
+ const gateScript = () => workflowScript("enforce-pr-target.yml", "enforce-target", "Enforce PR target and description");
test("a gate rebuild keeps the record, so the next hygiene run keeps a current approval", async () => {
const existing = gateComment(["✅ **Deterministic PR hygiene checks passed.**", recordLine(HARNESS_HEAD, 0)]);
@@ -572,7 +572,7 @@ describe("gate preservation ignores marker text in echoed paths", () => {
test("a changed path containing the block marker text does not drop the record", async () => {
const existing = gateComment(["⚠️ **Deterministic hygiene checks failed.**", recordLine(HARNESS_HEAD, 0)]);
const gateRun = await runEnforcePrTarget(
- workflowScript("enforce-pr-target.yml", "enforce-target", "Enforce PR target, ancestry, and description"),
+ workflowScript("enforce-pr-target.yml", "enforce-target", "Enforce PR target and description"),
{
pr: { base: { ref: "dev" }, draft: true },
// new_suppression echoes this path into the rebuilt gate body.
diff --git a/tests/ci-workflows/ci-review-lanes.test.ts b/tests/ci-workflows/ci-review-lanes.test.ts
index 2d83451a9af..84c7fdcdddf 100644
--- a/tests/ci-workflows/ci-review-lanes.test.ts
+++ b/tests/ci-workflows/ci-review-lanes.test.ts
@@ -45,8 +45,13 @@ describe("CI review lanes", () => {
};
const trigger = workflow.on?.pull_request ?? {};
if (expectedKeys.includes("branches")) {
+ // `main` was deleted and `dev` is the only integration line. A PR base
+ // filter can only name integration lines, so the list is exactly
+ // `dev` — stacked child PRs are still covered because their base is a
+ // parent PR head, which no allowlist could enumerate and which this
+ // workflow did not cover before either.
const branches = (trigger.branches as string[] | undefined) ?? [];
- expect([...branches].sort()).toEqual(["dev", "main"]);
+ expect([...branches].sort()).toEqual(["dev"]);
}
// Narrowing a default is a mutation that deletes nothing. Omitting
@@ -73,6 +78,29 @@ describe("CI review lanes", () => {
};
expect(ci.on?.push).toBeUndefined();
+ // Workflows that used to run on the deleted `main`/`preview` branches shed
+ // those pushes instead of retargeting them. A `dev` push trigger is
+ // explicitly forbidden by the CI policy and would also turn a per-merge
+ // event into the expensive path this repository deliberately keeps manual.
+ for (const relPath of [
+ ".github/workflows/codex-queue-helpers.yml",
+ ".github/workflows/issue-quality-tests.yml",
+ ".github/workflows/cleanup-orphaned-workflows.yml",
+ ".github/workflows/react-doctor.yml",
+ ]) {
+ const workflow = Bun.YAML.parse(await readText(relPath)) as {
+ on?: Record & {
+ push?: { branches?: string[]; paths?: string[] };
+ };
+ };
+ expect(workflow.on?.push, `${relPath} must not push on a deleted branch`).toBeUndefined();
+ // The remaining useful coverage must survive the removal.
+ const triggerNames = Object.keys(workflow.on ?? {});
+ expect(triggerNames.length, `${relPath} must keep a trigger`).toBeGreaterThan(0);
+ expect(triggerNames.includes("pull_request") || triggerNames.includes("schedule"),
+ `${relPath} must keep PR or scheduled coverage`).toBe(true);
+ }
+
// The PR trigger must carry NO base-branch filter, and the two triggers
// differ on purpose. GitHub matches `branches:` against the BASE ref, so
// `[main, dev]` silently excluded stacked child PRs — whose base is another
diff --git a/tests/ci-workflows/ci-workflows.test.ts b/tests/ci-workflows/ci-workflows.test.ts
index 6ee7cab0002..d1a76a552f3 100644
--- a/tests/ci-workflows/ci-workflows.test.ts
+++ b/tests/ci-workflows/ci-workflows.test.ts
@@ -293,8 +293,8 @@ describe("GitHub Actions hardening", () => {
expect(macosTestStep?.run).not.toContain("for attempt in");
expect(macosTestStep?.run).not.toContain("while true");
expect((ci.jobs?.["platform-macos"] as { needs?: string; if?: string })?.needs).toBe("changes");
- // Pull requests never run macOS shards; they run after merge, on push to
- // dev/main/preview. ci-scope-reduction.test.ts evaluates this condition
+ // Pull requests never run macOS shards; they run only on a manual full
+ // dispatch from `dev`. ci-scope-reduction.test.ts evaluates this condition
// against the events that select the job.
expect((ci.jobs?.["platform-macos"] as { if?: string })?.if).toBe("github.event_name != 'pull_request'");
@@ -465,10 +465,10 @@ describe("GitHub Actions hardening", () => {
steps?: { with?: Record }[];
})?.steps?.find(step => step.with?.filters);
- // `base` is not cosmetic. Unset, paths-filter diffs a `dev` push against the
- // repository default branch (`main`), so everything changed since the last
- // promotion still reads as changed and the scoped jobs run anyway — the
- // filter would look correct, stay green, and save nothing.
+ // `base` is not cosmetic. Unset, paths-filter diffs against the repository
+ // default branch (`dev`), so everything changed since the branch point still
+ // reads as changed and the scoped jobs run anyway — the filter would look
+ // correct, stay green, and save nothing.
expect(filterStep?.with?.base).toBe("${{ github.ref }}");
// paths-filter cannot read a PR's file list without this, and a filter that
@@ -946,7 +946,6 @@ describe("GitHub Actions hardening", () => {
"issues.listComments",
"repos.getCollaboratorPermissionLevel",
"repos.compareCommitsWithBasehead",
- "repos.compareCommitsWithBasehead",
"pulls.get",
"pulls.listFiles",
"pulls.get",
@@ -957,7 +956,7 @@ describe("GitHub Actions hardening", () => {
];
}
- /** Reads for a PR whose base is outside the allow-list (no ancestry compares). */
+ /** Reads for a PR whose base is outside the allow-list (no base compare). */
function readsWrongBase(tail: string[] = []): string[] {
return [
...SCRIPT_LOAD,
@@ -982,7 +981,6 @@ describe("GitHub Actions hardening", () => {
"issues.listComments",
"repos.getCollaboratorPermissionLevel",
"repos.compareCommitsWithBasehead",
- "repos.compareCommitsWithBasehead",
// The harness walks every paginate call across the same page count, so
// listFiles appears once per comment page even when the file list is empty.
"pulls.get",
@@ -1089,9 +1087,9 @@ describe("GitHub Actions hardening", () => {
// And the trigger is exactly a `types:` list — nothing else.
//
// Every other level here is pinned by exact key-set equality; this one was
- // not, and a review round walked straight through the hole. `branches: [main]`
- // narrows the gate to PRs against `main`, so one opened against `preview`
- // sails past unenforced. `paths:` is worse: the gate then fires only when
+ // not, and a review round walked straight through the hole. A `branches:`
+ // filter narrows the gate to PRs against the listed bases, so one opened
+ // against any other base sails past unenforced. `paths:` is worse: the gate then fires only when
// particular files change, which on a docs-only PR means never. Both are
// additive, both look like ordinary scoping in a diff, and neither failed a
// single assertion.
@@ -1186,16 +1184,14 @@ describe("GitHub Actions hardening", () => {
"sparse-checkout",
]);
expect(checkout.with).toEqual({
- // The trusted ref comes from a fixed set of integration branches, never
- // from the pull request: a stacked child's base is another open PR's
- // head, so an unpromoted commit must not select the code that runs with
- // this workflow's write-capable token. A `status` event has no
- // pull_request payload and loads scripts from the default-branch trust
- // boundary that owns the event; a `main`-targeting PR loads from `main`
- // so the scripts match the workflow definition `pull_request_target`
- // itself loaded; everything else resolves to `dev`.
- ref:
- "${{ github.event_name == 'status' && github.event.repository.default_branch || (github.event.pull_request.base.ref == 'main' && 'main' || 'dev') }}",
+ // The trusted ref is never the pull request: a stacked child's base is
+ // another open PR's head, so an unpromoted commit must not select the
+ // code that runs with this workflow's write-capable token. `dev` is the
+ // only integration line now, so a `pull_request_target` run always reads
+ // scripts from `dev`. A `status` event has no pull_request payload and
+ // loads scripts from the default-branch trust boundary that owns the
+ // event, spelled as the repository default rather than a literal.
+ ref: "${{ github.event_name == 'status' && github.event.repository.default_branch || 'dev' }}",
"persist-credentials": false,
// MAINTAINERS.md rides along so the completion ping reads the canonical
// maintainer list from the same trusted base revision as the scripts.
@@ -1263,7 +1259,7 @@ describe("GitHub Actions hardening", () => {
expect(workflow.on?.pull_request_review).toBeUndefined();
expect(workflow.on?.pull_request_review_comment).toBeUndefined();
- // The verdict is a live PR read plus ancestry/description checks.
+ // The verdict is a live PR read plus base-compare/description checks.
expect(script).toContain("github.rest.pulls.get");
expect(script).toContain("collectPrQualityFailures");
expect(script).toContain("collectDeterministicHygieneFailures");
@@ -2779,44 +2775,28 @@ describe("GitHub Actions hardening", () => {
).toBe(true);
});
- const HEAD_SHA = "3f1c0de0a6a4d0a3f9a1b2c3d4e5f60718293a4b";
- const ANCESTRY_FAIL_COMPARES = {
- [`main...${HEAD_SHA}`]: { ahead_by: 1, behind_by: 0 },
- [`dev...${HEAD_SHA}`]: { ahead_by: 0, behind_by: 44 },
- } as const;
-
- test("wrong ancestry on dev fails without title prefix (#644)", async () => {
+ test("a contributor head far behind dev is reported through readiness, not wrong ancestry", async () => {
+ // The deleted `main` tip used to back a second `main...head` comparison
+ // and a `wrong_ancestry` failure. `dev` is the only integration branch
+ // now, so a stale head is a readiness-claim concern, not a wrong-target
+ // one: exactly one compare runs and no ancestry failure is raised.
const result = await run({
pr: { base: { ref: "dev" } },
authorPermission: "read",
- compareByBasehead: ANCESTRY_FAIL_COMPARES,
+ compareByBasehead: {
+ "dev...3f1c0de0a6a4d0a3f9a1b2c3d4e5f60718293a4b": { ahead_by: 0, behind_by: 44 },
+ },
});
- // No wrong base, so no title write — the checklist injection is the only
- // `pulls.update`, and the contributor flow writes the ownership
- // checkpoint comment before the draft conversion.
expect(methodsOf(result)).toEqual(readsAllowedBase([
"pulls.update",
"issues.createComment",
"graphql",
]));
const commentBody = lastEnforcerCommentBody(result);
- expect(commentBody).toContain("wrong branch ancestry");
+ expect(commentBody).not.toContain("wrong branch ancestry");
expect(commentBody).not.toContain("wrong target branch");
- expect(commentBody).toContain("## Review readiness checklist");
- expect(result.warnings.some((w) => w.startsWith("setFailed:"))).toBe(true);
- expect(result.warnings.some((w) => w.includes("wrong ancestry"))).toBe(true);
- });
-
- test("maintainers skip ancestry enforcement with the same compares", async () => {
- const result = await run({
- pr: { base: { ref: "dev" } },
- authorPermission: "write",
- compareByBasehead: ANCESTRY_FAIL_COMPARES,
- });
-
- expect(methodsOf(result)).toEqual(readsAllowedBase());
- expect(result.warnings.some((w) => w.startsWith("setFailed:"))).toBe(false);
+ expect(result.warnings.some((w) => w.includes("wrong ancestry"))).toBe(false);
});
test("empty PR description fails and drafts", async () => {
@@ -5177,15 +5157,17 @@ describe("GitHub Actions hardening", () => {
test("React Doctor workflow is SHA-pinned, engine-pinned, gating, and read-only", async () => {
const workflow = await readText(".github/workflows/react-doctor.yml");
- // Pull requests scan only when gui/ (the scanned directory) or this workflow changes;
- // the main push trend scan stays unfiltered.
+ // Pull requests scan only when gui/ (the scanned directory) or this workflow changes.
const triggers = (Bun.YAML.parse(workflow) as {
on?: { pull_request?: { types?: string[]; paths?: string[] }; push?: { branches?: string[]; paths?: string[] } };
}).on;
expect(triggers?.pull_request?.types).toEqual(["opened", "synchronize", "reopened", "ready_for_review"]);
expect(triggers?.pull_request?.paths).toEqual(["gui/**", ".github/workflows/react-doctor.yml"]);
expect(workflow).toContain("directory: gui");
- expect(triggers?.push).toEqual({ branches: ["main"] });
+ // The health-score push trend ran only on the deleted `main` branch. A
+ // `dev` push trigger is forbidden by the CI policy, so only PR coverage
+ // remains.
+ expect(triggers?.push).toBeUndefined();
expect(workflow).toContain("actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8");
expect(workflow).toContain("millionco/react-doctor@01820bb4fd4d0a4aebcd8df2b2a143a098649cb2");
diff --git a/tests/ci-workflows/cleanup-orphaned-workflows.test.ts b/tests/ci-workflows/cleanup-orphaned-workflows.test.ts
index bfe99aface1..5db6dc5d8c1 100644
--- a/tests/ci-workflows/cleanup-orphaned-workflows.test.ts
+++ b/tests/ci-workflows/cleanup-orphaned-workflows.test.ts
@@ -30,9 +30,9 @@ function mockFetch(routes: MockRoute[], calls: string[]) {
function baseRoutes(extra: MockRoute[]): MockRoute[] {
return [
- { path: "/repos/lidge-jun/opencodex", body: { default_branch: "main" } },
+ { path: "/repos/lidge-jun/opencodex", body: { default_branch: "dev" } },
{
- path: "/repos/lidge-jun/opencodex/contents/.github/workflows?ref=main",
+ path: "/repos/lidge-jun/opencodex/contents/.github/workflows?ref=dev",
body: [
{ type: "file", path: ".github/workflows/ci.yml" },
{ type: "file", path: ".github/workflows/cleanup-orphaned-workflows.yml" },
@@ -56,7 +56,10 @@ describe("orphaned GitHub Actions cleanup", () => {
}>;
};
- expect(Object.keys(workflow.on ?? {}).sort()).toEqual(["push", "schedule"]);
+ // Only the daily schedule remains. The old one-time `push` on `main` was a
+ // backlog bootstrap for a branch that no longer exists, and a `dev` push
+ // trigger is forbidden by policy.
+ expect(Object.keys(workflow.on ?? {}).sort()).toEqual(["schedule"]);
expect(workflow.permissions).toEqual({
actions: "write",
contents: "read",
diff --git a/tests/ci-workflows/linux-desktop-packaged-ci.test.ts b/tests/ci-workflows/linux-desktop-packaged-ci.test.ts
index ad3d52a4ce1..f439dea1467 100644
--- a/tests/ci-workflows/linux-desktop-packaged-ci.test.ts
+++ b/tests/ci-workflows/linux-desktop-packaged-ci.test.ts
@@ -28,7 +28,7 @@ describe("Linux packaged desktop E2E in CI", () => {
const filters = String(filter?.with?.filters ?? "");
expect(filters).toContain("desktop:");
// The package E2E filter: only packaging inputs select it on a pull request. Ordinary
- // src/** and gui/** edits are left to promotion pushes and workflow_dispatch.
+ // src/** and gui/** edits are covered by manual workflow_dispatch evidence.
const desktopFilter = filters.split(/\n(?=\s{0,2}\S[^\n]*:\s*$)/m)
.find(block => /^\s*desktop:\s*$/m.test(block.split("\n")[0] ?? "")) ?? "";
const desktopPaths = [...desktopFilter.matchAll(/- '([^']+)'/g)].map(match => match[1]);
diff --git a/tests/ci-workflows/pr-readiness-reattest.test.ts b/tests/ci-workflows/pr-readiness-reattest.test.ts
index d6da586dc95..2fe9121753c 100644
--- a/tests/ci-workflows/pr-readiness-reattest.test.ts
+++ b/tests/ci-workflows/pr-readiness-reattest.test.ts
@@ -18,7 +18,7 @@ const T5 = "2026-09-22T00:00:10Z";
const workflow = Bun.YAML.parse(readFileSync(repoPath(".github/workflows/enforce-pr-target.yml"), "utf8")) as {
jobs: Record }>;
};
-const script = workflow.jobs["enforce-target"]!.steps.find(step => step.name === "Enforce PR target, ancestry, and description")!.with!.script!;
+const script = workflow.jobs["enforce-target"]!.steps.find(step => step.name === "Enforce PR target and description")!.with!.script!;
function body(label = CURRENT, checks = 4): string {
return ["## Summary", "", "Update managed validation wording while preserving the author's text and explicitly requiring a fresh attestation.", "",
diff --git a/tests/ci-workflows/zz-pr-coderabbit-readiness-revalidation.test.ts b/tests/ci-workflows/zz-pr-coderabbit-readiness-revalidation.test.ts
index 101bd9f6871..172d7b6c0ca 100644
--- a/tests/ci-workflows/zz-pr-coderabbit-readiness-revalidation.test.ts
+++ b/tests/ci-workflows/zz-pr-coderabbit-readiness-revalidation.test.ts
@@ -73,7 +73,7 @@ async function readGateScript(): Promise {
).text();
const workflow = Bun.YAML.parse(text) as Workflow;
const script = workflow.jobs?.["enforce-target"]?.steps?.find(
- step => step.name === "Enforce PR target, ancestry, and description",
+ step => step.name === "Enforce PR target and description",
)?.with?.script;
if (typeof script !== "string") {
throw new Error("enforce-target step has no inline script");
@@ -133,16 +133,16 @@ describe("workflow comment-spam hardening", () => {
const checkoutStep = job?.steps?.find(
step => step.name === "Checkout trusted PR-quality scripts",
);
- // Trusted scripts come from a fixed set of integration branches, never
- // from the pull request itself. `status` keeps the default-branch
- // boundary that owns the event; a `main`-targeting PR matches the workflow
- // definition loaded from `main`; every other base resolves to `dev`.
+ // Trusted scripts come from `dev`, never from the pull request itself.
+ // `status` has no PR payload and keeps the default-branch boundary that
+ // owns the event; every pull_request event, including a stacked child's,
+ // resolves to `dev`, the single integration branch.
expect(checkoutStep?.with?.ref).toBe(
- "${{ github.event_name == 'status' && github.event.repository.default_branch || (github.event.pull_request.base.ref == 'main' && 'main' || 'dev') }}",
+ "${{ github.event_name == 'status' && github.event.repository.default_branch || 'dev' }}",
);
const gateStep = job?.steps?.find(
- step => step.name === "Enforce PR target, ancestry, and description",
+ step => step.name === "Enforce PR target and description",
);
const script = gateStep?.with?.script ?? "";
expect(gateStep?.env?.RESOLVED_PULL_NUMBER).toBe(
diff --git a/tests/helpers/enforce-pr-target-harness.ts b/tests/helpers/enforce-pr-target-harness.ts
index 3657cbc56d9..d22f48c23d2 100644
--- a/tests/helpers/enforce-pr-target-harness.ts
+++ b/tests/helpers/enforce-pr-target-harness.ts
@@ -788,10 +788,6 @@ export async function runEnforcePrTarget(
function compareResult(basehead: string): { ahead_by: number; behind_by: number } {
const override = options.compareByBasehead?.[basehead];
if (override) return override;
- if (basehead.startsWith("main...")) {
- // Default: not the #644 shape (several commits ahead of main).
- return { ahead_by: 8, behind_by: 0 };
- }
return { ahead_by: 0, behind_by: 0 };
}
@@ -1087,7 +1083,7 @@ export async function runEnforcePrTarget(
id: 987654321,
name: "opencodex",
full_name: "lidge-jun/opencodex",
- default_branch: "main",
+ default_branch: "dev",
private: false,
owner: { login: "lidge-jun", id: 12345, type: "User" },
html_url: "https://github.com/lidge-jun/opencodex",