Skip to content

Instantly share code, notes, and snippets.

@pengx17
pengx17 / fix-chatgpt-codex-slack-connector.md
Created August 12, 2026 10:09
Fix ChatGPT/Codex Slack connector stuck in an OAuth reauthentication loop

修复 ChatGPT / Codex 的 Slack Connector 反复要求重新认证

适用症状:Slack 工具持续提示重新认证,错误原因为 oauth_refresh_token_rejected;重启应用、重开任务或普通 Reconnect 后仍然失败。

本文来自一次 2026-07-29 的 macOS 实际排查。ChatGPT 的界面名称可能变化, 但判断方法和恢复原则不依赖具体菜单文案。

先说结论

@pengx17
pengx17 / index.html
Created June 17, 2026 02:24
Cue Product Progress Dashboard
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cue Product Progress — 2026-06-17</title>
<style>
:root {
--bg: #0d1117;
--card: #161b22;
- Upgrade powershell
- https://learn.microsoft.com/zh-cn/powershell/scripting/whats-new/migrating-from-windows-powershell-51-to-powershell-7?view=powershell-7.3
- https://github.com/PowerShell/PowerShell/releases/download/v7.3.6/PowerShell-7.3.6-win-x64.msi
- Also add the shell to Terminal
- chocolatey
- cmd
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "[System.Net.ServicePointManager]::SecurityProtocol = 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
- powershell
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
- startship
@pengx17
pengx17 / graph.js
Created April 9, 2024 15:14
Draw affine workspace graph
function preparePageNodes() {
// id -> links
const pages = Array.from(currentWorkspace.docCollection.meta.docs).filter(p => p.title);
const edges = pages.flatMap((page) =>
getPageLinks(page.id).map((target) => [page.id, target])
);
return {
nodes: pages.map((page) => ({ id: page.id, label: page.title })),
edges: edges.map(([source, target]) => ({ source, target })),
};
@pengx17
pengx17 / patch.sh
Last active March 28, 2024 16:38
patch AppRun
# Adopted from https://gist.github.com/neilcsmith-net/69bcb23bcc6698815438dc4e3df6caa3
# INPUT_APPIMAGE must be absolute path
INPUT_APPIMAGE=$1
# System architecture to create AppImage for - see options at https://github.com/AppImage/AppImageKit/releases/continuous/
SYSTEM_ARCH="x86_64"
APPIMAGETOOL_URL="https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-$SYSTEM_ARCH.AppImage"
TMP_DIR=$(mktemp -d)
@pengx17
pengx17 / main.ts
Created January 27, 2024 15:16
transform to cssVar
import * as babel from "@babel/core";
import * as fs from "fs";
import plugin from "./plugin";
const code = fs.readFileSync('./input.ts', 'utf8');
const out = babel.transformSync(code, {
plugins: [plugin],
filename: './input.ts',
presets: [require.resolve("@babel/preset-typescript")],
@pengx17
pengx17 / export.js
Last active December 26, 2023 10:12
export current workspace snapshot in affine
(async () => {
// make sure ZipTransformer is imported and attached to window
const { ZipTransformer } = window;
await Promise.all([...currentWorkspace.blockSuiteWorkspace.pages.values()].map(p => p.load()));
// wait for a few more seconds
await new Promise(resolve => setTimeout(resolve, 5000));
const zipblob = await ZipTransformer.exportPages(currentWorkspace.blockSuiteWorkspace, [...currentWorkspace.blockSuiteWorkspace.pages.values()]);
const url = URL.createObjectURL(zipblob);
const a = document.createElement('a');
a.setAttribute('href', url);
@pengx17
pengx17 / export.js
Last active January 23, 2026 04:40
Export app.affine.pro and import into AFFiNE client
(async () => {
async function blobToBase64(blob) {
return await new Promise((resolve) => {
const reader = new FileReader();
reader.onload = function() {
resolve(reader.result.split(',')[1]);
}
reader.readAsDataURL(blob);
});
}
@pengx17
pengx17 / footprints.js
Last active April 11, 2023 01:49
get blocksuite size footsprints
(async () => {
const { getBlocksuiteReader } = await import(
"https://unpkg.com/blocksuite-reader@0.0.6/dist/index.js"
);
const workspace = window.currentBlockSuiteWorkspace;
const workspaceId = workspace.room;
const reader = getBlocksuiteReader({
workspaceId: workspaceId,
Y: workspace.constructor.Y,
});
@charset "utf-8";/*! tailwindcss v2.2.4 | MIT License | https://tailwindcss.com *//*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */*,::after,::before{box-sizing:border-box}html{-moz-tab-size:4;tab-size:4}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}body{font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'}hr{height:0;color:inherit}abbr[title]{text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance: