* fix(tlon): keep fragment image URLs as media
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
* test(tlon): prove fragment image media send path
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
* test(tlon): remove mocked fragment outbound proof
Keep the PR evidence scoped to the helper-level regression test until live Tlon proof is available. The mocked outbound test was not sufficient for the reviewer-requested live behavior proof and triggered serialized-state review noise.
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
* docs: refresh docs map for CI
Regenerate docs/docs_map.md after syncing with upstream/main so the docs map check passes on this PR branch.
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
* fix(tlon): constrain fragment image URL matching
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
* fix(tlon): harden image URL classification
Co-authored-by: VectorPeak <garrufariw@gmail.com>
---------
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Co-authored-by: VectorPeak <VectorPeak@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(github-copilot): reject unsupported OAuth enterprise domain before refresh and model routing
Legacy github-copilot OAuth credentials can carry a non-github.com
enterpriseUrl. The token-refresh path templated it into the endpoint and
sent the bearer refresh token there with no allowlist, and the model
routing path derived a base URL from the same credential, so an unexpired
credential kept routing its access token to that origin without ever
reaching a refresh.
A persisted credential origin that is not on the Copilot host allowlist
is now rejected before any request is issued and before any model URL is
produced. Because an off-allowlist origin means the stored access token
may itself have been minted by that origin, the credential is refused as
a whole rather than coerced to github.com: modifyModels withholds the
github-copilot models so the token has no route, and its proxy-ep is
never trusted. Login rejects an unsupported host up front, so every path
that turns a domain into a bearer-bearing URL validates first.
formatAuthDoctorHint guides affected users to re-authenticate, mirroring
the qwen-portal hint. Supported hosts are unchanged: github.com and
*.ghe.com data-residency tenants still route and refresh as before.
The allowlist plus a new isSupportedGithubCopilotDomain predicate move to
a dependency-free plugin-sdk leaf so the core OAuth runtime can share them
without closing a module cycle; plugin-sdk/provider-auth re-exports
normalizeGithubCopilotDomain, so the plugin-owned GitHub Copilot provider
keeps its existing import.
Fixes#103078.
* fix(github-copilot): resolve provider auth base conflict
* fix(github-copilot): resolve provider auth base conflict
* fix(github-copilot): validate token proxy endpoint
* fix(github-copilot): remove stale helper import
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
The desktop companion crate was Linux-only. All platform-specific code
lives in canvas.rs (WebKitGTK, cairo, unix sockets, SO_PEERCRED), so:
move webkit2gtk/cairo-rs/libc under linux target dependencies, gate the
canvas module, its protocol registration, invoke handler, and exit
shutdown to Linux, add a USERPROFILE home fallback and an explicit
no-op installer error for Windows, and add the multi-size icon.ico
Windows resource. Linux behavior is unchanged; macOS/Windows builds are
for testing (macOS cargo build+test green locally; Windows aarch64-msvc
built and launched in a Windows 11 ARM VM).
* fix(doctor): preserve allowlist entries for version-bound runtime plugins (codex) during stale config scan
* fix(doctor): restore codex to scanner stale expectation, protect at repair-sequencing
Scanner now flags codex in plugins.allow as stale so diagnostics are visible.
Repair-sequencing preserves the entry via preservePluginIds which already
includes VERSION_BOUND_RUNTIME_PLUGIN_IDS.
* fix(doctor): scope version-bound runtime plugin preservation to allow surface only
ClawSweeper P2: VERSION_BOUND_RUNTIME_PLUGIN_IDS was applied globally
across all stale config surfaces (deny, entries, slots, channels, etc.),
but only plugins.allow needs preservation. Move to a surface-scoped
parameter surfacePreservePluginIds so codex is preserved only in allow.
* fix(doctor): harden version-bound allowlist repair
* fix(doctor): retain version-bound plugin policy
* fix(doctor): align version-bound plugin diagnostics
Co-authored-by: hailory <hailory@xydigit.com>
---------
Co-authored-by: hailory <hailory@xydigit.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(config): reject zero-value resetArchiveRetention to prevent silent data loss
* fix: add braces to guard clauses for curly lint rule
* fix: normalize numeric values and cover pruneAfter fallback in migration
* fix: reject zero-value pruneAfter at schema level to close fallback gap
* fix: independently check and repair both retention fields in migration
* fix: split doctor diagnostics into field-specific rules and messages
* fix: remove unused local in migration test helper
* fix: repair 5 lint errors (curly braces, zero-fraction, narrow value)
* fix(doctor): rewrite zero resetArchiveRetention to false instead of deleting it
Deleting a zero resetArchiveRetention caused the runtime to fall back to
pruneAfter (default 30d), which contradicted the doctor output that
claimed archives would be kept indefinitely. Only an explicit false
value produces indefinite retention per the documented schema.
- P1: Rewrite zero resetArchiveRetention to false in the doctor
migration apply callback, matching the promised indefinite-retention
behavior.
- P3: Update the pruneAfter rule warning to describe eligible
stale/non-preserved session entries instead of "all sessions".
* fix(config): repair zero retention safely
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
* fix(config): warn before stripping JSON5 comments on config write
Add checkCommentLossWarning in json5-comments.ts to detect JSON5 comments
before config writes. Warn via deps.logger.warn for main config writes and
via options.warn for $include file writes. Both paths support skipOutputLogs
to suppress warnings during automated operations.
Fixes#105683
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(config): remove public warn callback, route through internal sink
Fixes#105683
- Remove warn field from exported ConfigWriteOptions (P1 merge-risk)
- Default checkCommentLossWarning to console.warn when no callback
- Move include warning after hash-conflict/rejection checks
- Update tests to spy on console.warn instead of custom callback
* fix(config): warn before stripping JSON5 comments
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>