Skip to content

Commit ca37710

Browse files
Merge remote-tracking branch 'origin/main' into fix/git-missing-ref-reason
2 parents b0ef3b3 + f0fb0e8 commit ca37710

390 files changed

Lines changed: 16594 additions & 2626 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/deploy-relay.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
deploy_relay:
2828
name: Deploy production relay
2929
# A manual run from another branch would deploy that branch to production.
30-
if: github.ref == 'refs/heads/main'
30+
if: github.repository == 'pingdotgg/t3code' && github.ref == 'refs/heads/main'
3131
runs-on: blacksmith-8vcpu-ubuntu-2404
3232
timeout-minutes: 15
3333
environment:

‎.github/workflows/mobile-android-apk.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ concurrency:
1515
jobs:
1616
mirror:
1717
name: Mirror beta APK
18+
if: github.repository == 'pingdotgg/t3code'
1819
runs-on: blacksmith-2vcpu-ubuntu-2404
1920
timeout-minutes: 10
2021
permissions:

‎.github/workflows/mobile-eas-production.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ concurrency:
7575
jobs:
7676
production:
7777
name: EAS ${{ inputs.profile || 'production' }} ${{ github.event_name == 'push' && 'auto' || inputs.mode }}
78+
if: github.repository == 'pingdotgg/t3code'
7879
runs-on: blacksmith-8vcpu-ubuntu-2404
7980
permissions:
8081
contents: read

‎.github/workflows/publish-aur.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ concurrency:
3737
jobs:
3838
publish:
3939
name: Validate and publish
40+
if: github.repository == 'pingdotgg/t3code'
4041
runs-on: blacksmith-8vcpu-ubuntu-2404
4142
timeout-minutes: 30
4243
container:

‎.github/workflows/release.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ jobs:
5050
# have already run. Scheduled runs also decide here whether a nightly is due.
5151
resolve_commit:
5252
name: Resolve release commit
53+
if: github.repository == 'pingdotgg/t3code'
5354
runs-on: blacksmith-8vcpu-ubuntu-2404
5455
timeout-minutes: 5
5556
outputs:

‎apps/desktop/scripts/build-preview-annotation-css.mjs‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,16 @@ const compilerInput = [
2929
annotationSource.replace('@import "tailwindcss";', "@tailwind utilities;"),
3030
].join("\n");
3131
const compiler = await compile(compilerInput, { base: appRoot });
32-
const css = compiler.build([...candidates]);
32+
// Shadow-root styles cannot register @property defaults. Make Tailwind's
33+
// fallback unconditional so border, shadow, and ring utilities have defaults.
34+
const compiledCss = compiler.build([...candidates]);
35+
const css = compiledCss.replace(
36+
/(@layer properties \{\n) @supports [^\n]*\{\n([\s\S]*?)\n \}\n(\})/,
37+
"$1$2\n$3",
38+
);
39+
if (css === compiledCss || /@layer properties\s*\{\s*@supports\b/.test(css)) {
40+
throw new Error("Tailwind @property fallback was not unwrapped; update the pattern above.");
41+
}
3342
const encodedCss = `'${css
3443
.replaceAll("\\", "\\\\")
3544
.replaceAll("'", "\\'")

‎apps/desktop/src/app/DesktopLinuxUrlHandler.test.ts‎

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,25 @@ describe("DesktopLinuxUrlHandler", () => {
179179
assert.include(entry, "Icon=/home/al ice/icons/T3\\\\x.png");
180180
});
181181

182+
it.each([
183+
{
184+
execTarget: "/opt/T3(beta)/t3code.AppImage",
185+
execLine: 'Exec="/opt/T3(beta)/t3code.AppImage" %U',
186+
},
187+
{
188+
execTarget: "/opt/t3%20code/t3code.AppImage",
189+
execLine: "Exec=/opt/t3%%20code/t3code.AppImage %U",
190+
},
191+
])("renders the handler Exec line for $execTarget", ({ execTarget, execLine }) => {
192+
const entry = DesktopLinuxUrlHandler.renderUrlHandlerDesktopEntry({
193+
displayName: "T3 Code",
194+
execTarget,
195+
scheme: "t3code",
196+
});
197+
198+
assert.include(entry.split("\n"), execLine);
199+
});
200+
182201
it("carries structured context on registration errors", () => {
183202
const writeError = new DesktopLinuxUrlHandler.DesktopLinuxUrlHandlerRegistrationError({
184203
step: "write-desktop-entry",
@@ -222,7 +241,7 @@ describe("DesktopLinuxUrlHandler", () => {
222241
);
223242
assert.include(
224243
recorded.files[0]?.content,
225-
'Exec="/home/alice/Applications/T3-Code.AppImage" %U',
244+
"Exec=/home/alice/Applications/T3-Code.AppImage %U",
226245
);
227246
assert.include(recorded.files[0]?.content, "MimeType=x-scheme-handler/t3code;");
228247
assert.deepEqual(recorded.commands, [
@@ -247,7 +266,12 @@ describe("DesktopLinuxUrlHandler", () => {
247266

248267
assert.include(
249268
recorded.files[0]?.content,
250-
`Exec=${DesktopLinuxUrlHandler.escapeDesktopEntryExecArgument(process.execPath)} %U`,
269+
DesktopLinuxUrlHandler.renderUrlHandlerDesktopEntry({
270+
displayName: "T3 Code (Alpha)",
271+
execTarget: process.execPath,
272+
scheme: "t3code",
273+
iconPath: "/home/alice/.local/share/icons/com.t3tools.T3Code.desktop.png",
274+
}),
251275
);
252276
});
253277
});

‎apps/desktop/src/app/DesktopLinuxUrlHandler.ts‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ export function escapeDesktopEntryExecArgument(value: string): string {
7575
return escapeDesktopEntryString(`"${quoted}"`);
7676
}
7777

78+
// Legacy xdg-open looks up the first Exec word without unquoting it.
79+
const escapeUrlHandlerExecTarget = (value: string): string =>
80+
/[ \t\n"'\\><~|&;$*?#()`]/.test(value)
81+
? escapeDesktopEntryExecArgument(value)
82+
: escapeDesktopEntryString(value.replaceAll("%", "%%"));
83+
7884
// The AppImage integration entry owns the window identity. This
7985
// hidden URL-only entry must not compete with it for StartupWMClass matching.
8086
export function renderUrlHandlerDesktopEntry(input: {
@@ -87,7 +93,7 @@ export function renderUrlHandlerDesktopEntry(input: {
8793
"[Desktop Entry]",
8894
"Type=Application",
8995
`Name=${escapeDesktopEntryString(input.displayName)}`,
90-
`Exec=${escapeDesktopEntryExecArgument(input.execTarget)} %U`,
96+
`Exec=${escapeUrlHandlerExecTarget(input.execTarget)} %U`,
9197
...(input.iconPath === undefined ? [] : [`Icon=${escapeDesktopEntryString(input.iconPath)}`]),
9298
"Terminal=false",
9399
"NoDisplay=true",

‎apps/desktop/src/app/DesktopPreReadyPlatform.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ describe("DesktopPreReadyPlatform", () => {
174174
);
175175
const identity = yield* Effect.promise(() => portalIdentity);
176176
assert.equal(identity.desktopName, "com.t3tools.T3Code.desktop");
177-
assert.include(identity.desktopEntry ?? "", 'Exec="/Applications/current.AppImage" %U');
177+
assert.include(identity.desktopEntry ?? "", "Exec=/Applications/current.AppImage %U");
178178
assert.include(identity.desktopEntry ?? "", "Name=T3 Code (Beta)");
179179
assert.include(identity.desktopEntry ?? "", "MimeType=x-scheme-handler/t3code;");
180180
assert.include(

‎apps/desktop/src/backend/DesktopBackendConfiguration.test.ts‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ describe("DesktopBackendConfiguration", () => {
551551
archiveHash: "b".repeat(64),
552552
wsl: () => ({
553553
prepareRuntime: () => ({ ok: false, reason: "archive is corrupt" }),
554+
invalidateRuntime: () => Effect.die("failed staging must not invalidate a runtime"),
554555
ensureNodePty: (_distro, root) => {
555556
observedNodePtyRoots.push(root);
556557
return { ok: true, nodePath: "/usr/bin/node", resolvedPath: "/usr/bin:/bin" };
@@ -615,6 +616,35 @@ describe("DesktopBackendConfiguration", () => {
615616
);
616617
});
617618

619+
it.effect("resolveWsl preserves the staging error when the mounted fallback is fatal", () =>
620+
withPackagedWslHarness(
621+
{
622+
archiveHash: "b".repeat(64),
623+
wsl: () => ({
624+
prepareRuntime: () => ({
625+
ok: false,
626+
reason:
627+
"t3: error while loading shared libraries: libatomic.so.1: cannot open shared object file",
628+
}),
629+
ensureNodePty: () => ({
630+
ok: false,
631+
reason: "the packaged Linux node-pty binary was not included",
632+
fatal: true,
633+
}),
634+
}),
635+
},
636+
() =>
637+
Effect.gen(function* () {
638+
const configuration = yield* DesktopBackendConfiguration.DesktopBackendConfiguration;
639+
const config = yield* configuration.resolveWsl({ port: 5000, distro: "Ubuntu" });
640+
const failure = Option.getOrThrow(config.preflightFailure);
641+
642+
assert.isTrue(failure.fatal);
643+
assert.include(failure.reason, "libatomic.so.1");
644+
}),
645+
),
646+
);
647+
618648
it.effect("resolveWsl keeps the staged runtime when the mounted tree fails too", () => {
619649
const stagedAppRoot = "/home/test/.t3/wsl-runtime/cache";
620650
const invalidatedRuntimeIds: string[] = [];

0 commit comments

Comments
 (0)