From f74c79f298a1b0253fb5b73dd0bd785d65b90c73 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Wed, 15 Apr 2026 13:51:50 -0700 Subject: [PATCH 1/3] Add lisan-al-gaib action --- .gitattributes | 1 + .github/workflows/ci.yml | 8 ++++++++ .github/workflows/e2e.yml | 2 ++ .github/workflows/lisan-al-gaib.yaml | 26 ++++++++++++++++++++++++++ .github/workflows/release.yml | 2 ++ package.json | 1 - pnpm-workspace.yaml | 3 +++ 7 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/lisan-al-gaib.yaml create mode 100644 pnpm-workspace.yaml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d62a2d9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +pnpm-lock.yaml -merge linguist-vendored diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5b1a39..9b52a3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,8 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v5 + with: + version: ^10.16 - name: Setup Node.js uses: actions/setup-node@v6 @@ -51,6 +53,8 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v5 + with: + version: ^10.16 - name: Setup Node.js uses: actions/setup-node@v6 @@ -79,6 +83,8 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v5 + with: + version: ^10.16 - name: Setup Node.js uses: actions/setup-node@v6 @@ -108,6 +114,8 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v5 + with: + version: ^10.16 - name: Setup Node.js uses: actions/setup-node@v6 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9f21572..b65718e 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -24,6 +24,8 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v5 + with: + version: ^10.16 - name: Setup Node.js uses: actions/setup-node@v6 diff --git a/.github/workflows/lisan-al-gaib.yaml b/.github/workflows/lisan-al-gaib.yaml new file mode 100644 index 0000000..6ed63c1 --- /dev/null +++ b/.github/workflows/lisan-al-gaib.yaml @@ -0,0 +1,26 @@ +name: "Dependency Check" +on: + push: + branches: [main] + paths: + - .github/workflows/lisan-al-gaib.yaml + - pnpm-lock.yaml + pull_request: + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-slim + steps: + - uses: runloopai/checkout@main + + - uses: runloopai/lisan-al-gaib-action@jason/playground + with: + ecosystems: npm,actions + bypass-keyword: cve-fix + age-overrides: | + npm: + - '@runloop/api-client' + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9385513..dc8a974 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,6 +34,8 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v5 + with: + version: ^10.16 - name: Setup Node.js uses: actions/setup-node@v6 diff --git a/package.json b/package.json index c630392..b873ca6 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "docs:commands": "pnpm run build && node scripts/generate-command-docs.js", "prepare": "husky" }, - "packageManager": "pnpm@9.15.4", "keywords": [ "runloop", "cli", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..fc9f80f --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +minimumReleaseAge: 20160 +minimumReleaseAgeExclude: + - '@runloop/api-client' From a3f5098fb42b46e62ae27049631dd7734345e990 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Wed, 15 Apr 2026 14:19:45 -0700 Subject: [PATCH 2/3] ditch cfonts GPL-3 dependency --- package.json | 1 - pnpm-lock.yaml | 91 --------------------------------------- src/components/Banner.tsx | 17 ++++++-- tests/setup-components.ts | 5 +-- tests/setup-router.ts | 5 +-- tests/setup.ts | 1 - 6 files changed, 17 insertions(+), 103 deletions(-) diff --git a/package.json b/package.json index b873ca6..6de53bd 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,6 @@ "figures": "^6.1.0", "gradient-string": "^3.0.0", "ink": "^6.6.0", - "ink-big-text": "^2.0.0", "ink-gradient": "^3.0.0", "ink-link": "^5.0.0", "ink-spinner": "^5.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 22ca7b1..d160137 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,9 +50,6 @@ importers: ink: specifier: ^6.6.0 version: 6.6.0(@types/react@19.2.10)(react@19.2.0) - ink-big-text: - specifier: ^2.0.0 - version: 2.0.0(ink@6.6.0(@types/react@19.2.10)(react@19.2.0))(react@19.2.0) ink-gradient: specifier: ^3.0.0 version: 3.0.0(ink@6.6.0(@types/react@19.2.10)(react@19.2.0)) @@ -1100,11 +1097,6 @@ packages: caniuse-lite@1.0.30001766: resolution: {integrity: sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==} - cfonts@3.3.1: - resolution: {integrity: sha512-ZGEmN3W9mViWEDjsuPo4nK4h39sfh6YtoneFYp9WLPI/rw8BaSSrfQC6jkrGW3JMvV3ZnExJB/AEqXc/nHYxkw==} - engines: {node: '>=10'} - hasBin: true - chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -1282,10 +1274,6 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - define-property@1.0.0: - resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} - engines: {node: '>=0.10.0'} - delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -1790,13 +1778,6 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ink-big-text@2.0.0: - resolution: {integrity: sha512-Juzqv+rIOLGuhMJiE50VtS6dg6olWfzFdL7wsU/EARSL5Eaa5JNXMogMBm9AkjgzO2Y3UwWCOh87jbhSn8aNdw==} - engines: {node: '>=14.16'} - peerDependencies: - ink: '>=4' - react: '>=18' - ink-gradient@3.0.0: resolution: {integrity: sha512-OVyPBovBxE1tFcBhSamb+P1puqDP6pG3xFe2W9NiLgwUZd9RbcjBeR7twLbliUT9navrUstEf1ZcPKKvx71BsQ==} engines: {node: '>=16'} @@ -1857,10 +1838,6 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - is-accessor-descriptor@1.0.1: - resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} - engines: {node: '>= 0.10'} - is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -1880,9 +1857,6 @@ packages: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} - is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -1891,10 +1865,6 @@ packages: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} - is-data-descriptor@1.0.1: - resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==} - engines: {node: '>= 0.4'} - is-data-view@1.0.2: resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} engines: {node: '>= 0.4'} @@ -1903,10 +1873,6 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} - is-descriptor@1.0.3: - resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==} - engines: {node: '>= 0.4'} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1952,10 +1918,6 @@ packages: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} - is-number@3.0.0: - resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} - engines: {node: '>=0.10.0'} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -2225,10 +2187,6 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - kind-of@3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -3053,11 +3011,6 @@ packages: resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} engines: {node: '>=18'} - window-size@1.1.1: - resolution: {integrity: sha512-5D/9vujkmVQ7pSmc0SCBmHXbkv6eaHwXEx65MywhmUMsI8sGqJ972APq1lotfcwMKPFLuCFfL8xGHLIp7jaBmA==} - engines: {node: '>= 0.10.0'} - hasBin: true - word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -4381,11 +4334,6 @@ snapshots: caniuse-lite@1.0.30001766: {} - cfonts@3.3.1: - dependencies: - supports-color: 8.1.1 - window-size: 1.1.1 - chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -4546,10 +4494,6 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 - define-property@1.0.0: - dependencies: - is-descriptor: 1.0.3 - delayed-stream@1.0.0: {} depd@2.0.0: {} @@ -5190,13 +5134,6 @@ snapshots: inherits@2.0.4: {} - ink-big-text@2.0.0(ink@6.6.0(@types/react@19.2.10)(react@19.2.0))(react@19.2.0): - dependencies: - cfonts: 3.3.1 - ink: 6.6.0(@types/react@19.2.10)(react@19.2.0) - prop-types: 15.8.1 - react: 19.2.0 - ink-gradient@3.0.0(ink@6.6.0(@types/react@19.2.10)(react@19.2.0)): dependencies: '@types/gradient-string': 1.1.6 @@ -5269,10 +5206,6 @@ snapshots: ipaddr.js@1.9.1: {} - is-accessor-descriptor@1.0.1: - dependencies: - hasown: 2.0.2 - is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -5298,18 +5231,12 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-buffer@1.1.6: {} - is-callable@1.2.7: {} is-core-module@2.16.1: dependencies: hasown: 2.0.2 - is-data-descriptor@1.0.1: - dependencies: - hasown: 2.0.2 - is-data-view@1.0.2: dependencies: call-bound: 1.0.4 @@ -5321,11 +5248,6 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-descriptor@1.0.3: - dependencies: - is-accessor-descriptor: 1.0.1 - is-data-descriptor: 1.0.1 - is-extglob@2.1.1: {} is-finalizationregistry@1.1.1: @@ -5363,10 +5285,6 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-number@3.0.0: - dependencies: - kind-of: 3.2.2 - is-number@7.0.0: {} is-promise@4.0.0: {} @@ -5825,10 +5743,6 @@ snapshots: dependencies: json-buffer: 3.0.1 - kind-of@3.2.2: - dependencies: - is-buffer: 1.1.6 - kleur@3.0.3: {} leven@3.1.0: {} @@ -6679,11 +6593,6 @@ snapshots: dependencies: string-width: 7.2.0 - window-size@1.1.1: - dependencies: - define-property: 1.0.0 - is-number: 3.0.0 - word-wrap@1.2.5: {} wordwrap@1.0.0: {} diff --git a/src/components/Banner.tsx b/src/components/Banner.tsx index 7855889..4a3627c 100644 --- a/src/components/Banner.tsx +++ b/src/components/Banner.tsx @@ -1,6 +1,5 @@ import React, { useState, useEffect, useRef } from "react"; import { Box, Text, useStdout } from "ink"; -import BigText from "ink-big-text"; import Gradient from "ink-gradient"; import { isLightMode } from "../utils/theme.js"; @@ -88,9 +87,19 @@ const LIGHT_FRAMES = precomputeFrames( LIGHT_SHIMMER_COLORS.filter((_, i) => i % 2 === 0), ); -// Minimum width to show the full BigText banner (simple3d font needs ~80 chars for "RUNLOOP.ai") +// Pre-rendered "RUNLOOP.ai" in simple3d font (previously rendered by cfonts via ink-big-text) +const BANNER_ART = `\ + ___ + _ __ __ __ ___ /\\_ \\ ___ ___ _____ __ __ +/\\\` __\\/\\ \\/\\ \\ /' _ \`\\ \\//\\ \\ / __\`\\ / __\`\\ /\\ '__\`\\ /'__\`\\ /\\_\\ +\\ \\ \\/ \\ \\ \\_\\ \\/\\ \\/\\ \\ \\_\\ \\_ /\\ \\_\\ \\/\\ \\_\\ \\\\ \\ \\_\\ \\ /\\ \\_\\.\\_ \\/\\ \\ + \\ \\_\\ \\ \\____/\\ \\_\\ \\_\\ /\\____\\\\ \\____/\\ \\____/ \\ \\ ,__/ __ \\ \\__/.\\_\\ \\ \\ \\ + \\/_/ \\/___/ \\/_/\\/_/ \\/____/ \\/___/ \\/___/ \\ \\ \\/ /\\_\\ \\/__/\\/_/ \\/_/ + \\/_/ \\/_/ `; + +// Minimum width to show the full banner (simple3d font needs ~80 chars for "RUNLOOP.ai") const MIN_WIDTH_FOR_BIG_BANNER = 90; -// Minimum height to show the full BigText banner - require generous room (40 lines) +// Minimum height to show the full banner - require generous room (40 lines) const MIN_HEIGHT_FOR_BIG_BANNER = 40; // Animation interval in ms @@ -169,7 +178,7 @@ export const Banner = React.memo(() => { return ( - + {BANNER_ART} ); diff --git a/tests/setup-components.ts b/tests/setup-components.ts index 9e40d14..8764f5f 100644 --- a/tests/setup-components.ts +++ b/tests/setup-components.ts @@ -126,8 +126,7 @@ jest.mock("ink-spinner", () => ({ default: () => null, })); -// Mock ink-big-text and ink-gradient (these cause ESM issues) -jest.mock("ink-big-text", () => ({ __esModule: true, default: () => null })); +// Mock ink-gradient (causes ESM issues) jest.mock("ink-gradient", () => ({ __esModule: true, default: () => null })); // Note: We do NOT mock 'ink' - we use ink-testing-library which needs real ink @@ -422,7 +421,7 @@ jest.mock("../src/utils/exec.ts", () => ({ execCommand: jest.fn(), })); -// Mock Banner component (uses ink-big-text which is ESM) +// Mock Banner component (uses ink-gradient which is ESM) jest.mock("../src/components/Banner.tsx", () => ({ __esModule: true, Banner: () => null, diff --git a/tests/setup-router.ts b/tests/setup-router.ts index 7b5bb9d..6ad69f9 100644 --- a/tests/setup-router.ts +++ b/tests/setup-router.ts @@ -127,8 +127,7 @@ jest.mock("ink-spinner", () => ({ default: () => null, })); -// Mock ink-big-text and ink-gradient (these cause ESM issues) -jest.mock("ink-big-text", () => ({ __esModule: true, default: () => null })); +// Mock ink-gradient (causes ESM issues) jest.mock("ink-gradient", () => ({ __esModule: true, default: () => null })); // Note: We do NOT mock 'ink' - we use ink-testing-library which needs real ink @@ -400,7 +399,7 @@ jest.mock("../src/utils/exec.ts", () => ({ execCommand: jest.fn(), })); -// Mock Banner component (uses ink-big-text which is ESM) +// Mock Banner component (uses ink-gradient which is ESM) jest.mock("../src/components/Banner.tsx", () => ({ __esModule: true, Banner: () => null, diff --git a/tests/setup.ts b/tests/setup.ts index a025467..051d538 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -65,7 +65,6 @@ jest.mock("ink", () => ({ })); // Mock ESM-only Ink dependencies so Jest doesn't parse their ESM bundles -jest.mock("ink-big-text", () => ({ __esModule: true, default: () => null })); jest.mock("ink-gradient", () => ({ __esModule: true, default: () => null })); // Mock app UI components that import Ink deps, to avoid pulling in ESM from node_modules From 719fb9584f6f4dede5f9c0ca8443e82ea1f50dff Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Wed, 15 Apr 2026 14:57:19 -0700 Subject: [PATCH 3/3] :) --- .github/workflows/lisan-al-gaib.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lisan-al-gaib.yaml b/.github/workflows/lisan-al-gaib.yaml index 6ed63c1..d822e52 100644 --- a/.github/workflows/lisan-al-gaib.yaml +++ b/.github/workflows/lisan-al-gaib.yaml @@ -16,7 +16,7 @@ jobs: steps: - uses: runloopai/checkout@main - - uses: runloopai/lisan-al-gaib-action@jason/playground + - uses: runloopai/lisan-al-gaib-action@main with: ecosystems: npm,actions bypass-keyword: cve-fix