Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .claude/agents/os-dev.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,8 +137,8 @@ pin 要防的失效 —— 而不是回退到本行。 -->
double** —— 不新增要 pin 的 double,不动台账。
- 匹配到零个脚本的 `pnpm --filter` 运行**以 0 退出**——什么都没跑,读上去却是通过;objectui
把 typecheck 拼作 `type-check`(连字符),拼错脚本名正好落进这个坑(拼对时依赖闭包没
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,或从 `PIPESTATUS` 读
退出码,⛔ 永不隔着管道 `tail` 下结论——ERR_PNPM 提示会被滚出视野
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,退出码先重定向再捕
,⛔ 永不隔着管道下结论——ERR_PNPM 会滚出视野,`| head` 连 `PIPESTATUS` 都改绿(见下节)
- 浏览器验证:Chromium **已预装**——`PLAYWRIGHT_BROWSERS_PATH` 指向 `/opt/pw-browsers`,launch 传
`executablePath: '/opt/pw-browsers/chromium'`。⛔ 永不跑 `playwright install`(出口策略拦它),且
`cdn.playwright.dev` 的 403 不是「没有浏览器」证据——下载被拦不证明产物缺席,先找产物。
Expand DownExpand Up@@ -185,15 +185,15 @@ pin 要防的失效 —— 而不是回退到本行。 -->
且没人会察觉 —— 迟到的 commit 挪动的恰恰是过期的 **ratchet** 读数。复核后任何一次
push,都在新 head 上重跑并集 —— 至少 ratchet 族 —— **然后**才更新报告或 PR 正文。

**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** `EXIT=$?` 跟
`cmd 2>&1 | tail -40` 之后,读到的是 **`tail` 的**状态:`tail` 基本永不失败,绿门禁与红门禁读出
来都是 `0`(实测:一次 typecheck 印着 `Exit status 2`,旁边的 `EXIT` 行写 `0`)。这不只是不可
靠,是**不可证伪**:对两种结局返回同一个值,重跑也翻不出来,却在报告里读作一次测量。三
种安全写法任选:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)·`set -o pipefail`·
`${PIPESTATUS[0]}`。另一半在报告侧:**引用某个门禁结果时,点名它自己印出的判定行**,永不引
裸 `$?` —— 判定行由门禁写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 agent 的 shell 用法
里,没有任何受版本控制的产物看得见它,已判定不可机械化 —— 这两条纪律就是全部的守
**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** 免疫写法
只有一种:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)。两个实测管道假绿,
同样**不可证伪**(红绿都回同一个 0,重跑翻不出来):① `EXIT=$?` 跟在 `cmd 2>&1 | tail -40` 之
后读到的是 **`tail` 的**状态;② `set -o pipefail` 与 `${PIPESTATUS[0]}` 仅当下游读到 EOF 才安全,
`| head -N` 是实测反例:读满即关读端,生产者吃 EPIPE/SIGPIPE 以 0 退出 —— 是管道改了生产者
的退出码,PIPESTATUS 如实上报,`pipefail` 读的也是同一个被改的状态。此陷阱不限于门禁:任何
`cmd | head` 之后读退出码都中招(`git grep`、`node` 皆然);读输出无事,读退出码即假绿。另一半
在报告侧:**引用门禁结果时,点名它自己印出的判定行**,永不引裸 `$?` —— 判定行由门禁
写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 shell 用法里,已判定不可机械化

**两类「跑了却没测到」,都读作 NOT MEASURED,不读作绿、也不读作红。** ① 包的 `typecheck` 可
能 `exclude` 掉 `**/*.test.ts` —— 于是「typecheck 干净」是一句真话,却对你新写的测试文件一个
Expand Down
6 changes: 4 additions & 2 deletions scripts/check-i18n-bundles.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -990,8 +990,10 @@ function reportPrerequisiteNotMet(headline, detail, options = {}) {
`\n\n Fix: ${fix}\n` +
alsoFix.map((l) => ` ${l}\n`).join('') +
`\n${nothingChecked}\n` +
` (Exit code 1 — but piping this gate reports the PIPE's status, so\n` +
` \`pnpm check:i18n | tail -4\` reads green either way. Use \`echo "EXIT=$?"\`.)`,
` (Exit code 1 — capture it BEFORE any pipe: \`pnpm check:i18n > /tmp/i18n.log 2>&1; echo "EXIT=$?"\`.\n` +
` Piped, \`$?\` is the pipe's status, and \`| head -N\` turns even \`\${PIPESTATUS[0]}\`/\`pipefail\` green:\n` +
` \`head\` closes the read end early, so this gate takes EPIPE and exits 0 — the pipe changed the\n` +
` exit code itself. \`| tail\` reads to EOF; \`\${PIPESTATUS[0]}\` after it is the true status.)`,
);
process.exit(1);
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(agents,scripts): PIPESTATUS/pipefail are exit-code-safe only when the downstream reads to EOF by zhuangjianguo · Pull Request #13427 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .claude/agents/os-dev.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,8 +137,8 @@ pin 要防的失效 —— 而不是回退到本行。 -->
double** —— 不新增要 pin 的 double,不动台账。
- 匹配到零个脚本的 `pnpm --filter` 运行**以 0 退出**——什么都没跑,读上去却是通过;objectui
把 typecheck 拼作 `type-check`(连字符),拼错脚本名正好落进这个坑(拼对时依赖闭包没
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,或从 `PIPESTATUS` 读
退出码,⛔ 永不隔着管道 `tail` 下结论——ERR_PNPM 提示会被滚出视野
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,退出码先重定向再捕
,⛔ 永不隔着管道下结论——ERR_PNPM 会滚出视野,`| head` 连 `PIPESTATUS` 都改绿(见下节)
- 浏览器验证:Chromium **已预装**——`PLAYWRIGHT_BROWSERS_PATH` 指向 `/opt/pw-browsers`,launch 传
`executablePath: '/opt/pw-browsers/chromium'`。⛔ 永不跑 `playwright install`(出口策略拦它),且
`cdn.playwright.dev` 的 403 不是「没有浏览器」证据——下载被拦不证明产物缺席,先找产物。
Expand DownExpand Up@@ -185,15 +185,15 @@ pin 要防的失效 —— 而不是回退到本行。 -->
且没人会察觉 —— 迟到的 commit 挪动的恰恰是过期的 **ratchet** 读数。复核后任何一次
push,都在新 head 上重跑并集 —— 至少 ratchet 族 —— **然后**才更新报告或 PR 正文。

**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** `EXIT=$?` 跟
`cmd 2>&1 | tail -40` 之后,读到的是 **`tail` 的**状态:`tail` 基本永不失败,绿门禁与红门禁读出
来都是 `0`(实测:一次 typecheck 印着 `Exit status 2`,旁边的 `EXIT` 行写 `0`)。这不只是不可
靠,是**不可证伪**:对两种结局返回同一个值,重跑也翻不出来,却在报告里读作一次测量。三
种安全写法任选:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)·`set -o pipefail`·
`${PIPESTATUS[0]}`。另一半在报告侧:**引用某个门禁结果时,点名它自己印出的判定行**,永不引
裸 `$?` —— 判定行由门禁写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 agent 的 shell 用法
里,没有任何受版本控制的产物看得见它,已判定不可机械化 —— 这两条纪律就是全部的守
**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** 免疫写法
只有一种:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)。两个实测管道假绿,
同样**不可证伪**(红绿都回同一个 0,重跑翻不出来):① `EXIT=$?` 跟在 `cmd 2>&1 | tail -40` 之
后读到的是 **`tail` 的**状态;② `set -o pipefail` 与 `${PIPESTATUS[0]}` 仅当下游读到 EOF 才安全,
`| head -N` 是实测反例:读满即关读端,生产者吃 EPIPE/SIGPIPE 以 0 退出 —— 是管道改了生产者
的退出码,PIPESTATUS 如实上报,`pipefail` 读的也是同一个被改的状态。此陷阱不限于门禁:任何
`cmd | head` 之后读退出码都中招(`git grep`、`node` 皆然);读输出无事,读退出码即假绿。另一半
在报告侧:**引用门禁结果时,点名它自己印出的判定行**,永不引裸 `$?` —— 判定行由门禁
写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 shell 用法里,已判定不可机械化

**两类「跑了却没测到」,都读作 NOT MEASURED,不读作绿、也不读作红。** ① 包的 `typecheck` 可
能 `exclude` 掉 `**/*.test.ts` —— 于是「typecheck 干净」是一句真话,却对你新写的测试文件一个
Expand Down
6 changes: 4 additions & 2 deletions scripts/check-i18n-bundles.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -990,8 +990,10 @@ function reportPrerequisiteNotMet(headline, detail, options = {}) {
`\n\n Fix: ${fix}\n` +
alsoFix.map((l) => ` ${l}\n`).join('') +
`\n${nothingChecked}\n` +
` (Exit code 1 — but piping this gate reports the PIPE's status, so\n` +
` \`pnpm check:i18n | tail -4\` reads green either way. Use \`echo "EXIT=$?"\`.)`,
` (Exit code 1 — capture it BEFORE any pipe: \`pnpm check:i18n > /tmp/i18n.log 2>&1; echo "EXIT=$?"\`.\n` +
` Piped, \`$?\` is the pipe's status, and \`| head -N\` turns even \`\${PIPESTATUS[0]}\`/\`pipefail\` green:\n` +
` \`head\` closes the read end early, so this gate takes EPIPE and exits 0 — the pipe changed the\n` +
` exit code itself. \`| tail\` reads to EOF; \`\${PIPESTATUS[0]}\` after it is the true status.)`,
);
process.exit(1);
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(agents,scripts): PIPESTATUS/pipefail are exit-code-safe only when the downstream reads to EOF by zhuangjianguo · Pull Request #13427 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .claude/agents/os-dev.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,8 +137,8 @@ pin 要防的失效 —— 而不是回退到本行。 -->
double** —— 不新增要 pin 的 double,不动台账。
- 匹配到零个脚本的 `pnpm --filter` 运行**以 0 退出**——什么都没跑,读上去却是通过;objectui
把 typecheck 拼作 `type-check`(连字符),拼错脚本名正好落进这个坑(拼对时依赖闭包没
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,或从 `PIPESTATUS` 读
退出码,⛔ 永不隔着管道 `tail` 下结论——ERR_PNPM 提示会被滚出视野
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,退出码先重定向再捕
,⛔ 永不隔着管道下结论——ERR_PNPM 会滚出视野,`| head` 连 `PIPESTATUS` 都改绿(见下节)
- 浏览器验证:Chromium **已预装**——`PLAYWRIGHT_BROWSERS_PATH` 指向 `/opt/pw-browsers`,launch 传
`executablePath: '/opt/pw-browsers/chromium'`。⛔ 永不跑 `playwright install`(出口策略拦它),且
`cdn.playwright.dev` 的 403 不是「没有浏览器」证据——下载被拦不证明产物缺席,先找产物。
Expand DownExpand Up@@ -185,15 +185,15 @@ pin 要防的失效 —— 而不是回退到本行。 -->
且没人会察觉 —— 迟到的 commit 挪动的恰恰是过期的 **ratchet** 读数。复核后任何一次
push,都在新 head 上重跑并集 —— 至少 ratchet 族 —— **然后**才更新报告或 PR 正文。

**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** `EXIT=$?` 跟
`cmd 2>&1 | tail -40` 之后,读到的是 **`tail` 的**状态:`tail` 基本永不失败,绿门禁与红门禁读出
来都是 `0`(实测:一次 typecheck 印着 `Exit status 2`,旁边的 `EXIT` 行写 `0`)。这不只是不可
靠,是**不可证伪**:对两种结局返回同一个值,重跑也翻不出来,却在报告里读作一次测量。三
种安全写法任选:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)·`set -o pipefail`·
`${PIPESTATUS[0]}`。另一半在报告侧:**引用某个门禁结果时,点名它自己印出的判定行**,永不引
裸 `$?` —— 判定行由门禁写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 agent 的 shell 用法
里,没有任何受版本控制的产物看得见它,已判定不可机械化 —— 这两条纪律就是全部的守
**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** 免疫写法
只有一种:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)。两个实测管道假绿,
同样**不可证伪**(红绿都回同一个 0,重跑翻不出来):① `EXIT=$?` 跟在 `cmd 2>&1 | tail -40` 之
后读到的是 **`tail` 的**状态;② `set -o pipefail` 与 `${PIPESTATUS[0]}` 仅当下游读到 EOF 才安全,
`| head -N` 是实测反例:读满即关读端,生产者吃 EPIPE/SIGPIPE 以 0 退出 —— 是管道改了生产者
的退出码,PIPESTATUS 如实上报,`pipefail` 读的也是同一个被改的状态。此陷阱不限于门禁:任何
`cmd | head` 之后读退出码都中招(`git grep`、`node` 皆然);读输出无事,读退出码即假绿。另一半
在报告侧:**引用门禁结果时,点名它自己印出的判定行**,永不引裸 `$?` —— 判定行由门禁
写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 shell 用法里,已判定不可机械化

**两类「跑了却没测到」,都读作 NOT MEASURED,不读作绿、也不读作红。** ① 包的 `typecheck` 可
能 `exclude` 掉 `**/*.test.ts` —— 于是「typecheck 干净」是一句真话,却对你新写的测试文件一个
Expand Down
6 changes: 4 additions & 2 deletions scripts/check-i18n-bundles.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -990,8 +990,10 @@ function reportPrerequisiteNotMet(headline, detail, options = {}) {
`\n\n Fix: ${fix}\n` +
alsoFix.map((l) => ` ${l}\n`).join('') +
`\n${nothingChecked}\n` +
` (Exit code 1 — but piping this gate reports the PIPE's status, so\n` +
` \`pnpm check:i18n | tail -4\` reads green either way. Use \`echo "EXIT=$?"\`.)`,
` (Exit code 1 — capture it BEFORE any pipe: \`pnpm check:i18n > /tmp/i18n.log 2>&1; echo "EXIT=$?"\`.\n` +
` Piped, \`$?\` is the pipe's status, and \`| head -N\` turns even \`\${PIPESTATUS[0]}\`/\`pipefail\` green:\n` +
` \`head\` closes the read end early, so this gate takes EPIPE and exits 0 — the pipe changed the\n` +
` exit code itself. \`| tail\` reads to EOF; \`\${PIPESTATUS[0]}\` after it is the true status.)`,
);
process.exit(1);
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(agents,scripts): PIPESTATUS/pipefail are exit-code-safe only when the downstream reads to EOF by zhuangjianguo · Pull Request #13427 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .claude/agents/os-dev.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,8 +137,8 @@ pin 要防的失效 —— 而不是回退到本行。 -->
double** —— 不新增要 pin 的 double,不动台账。
- 匹配到零个脚本的 `pnpm --filter` 运行**以 0 退出**——什么都没跑,读上去却是通过;objectui
把 typecheck 拼作 `type-check`(连字符),拼错脚本名正好落进这个坑(拼对时依赖闭包没
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,或从 `PIPESTATUS` 读
退出码,⛔ 永不隔着管道 `tail` 下结论——ERR_PNPM 提示会被滚出视野
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,退出码先重定向再捕
,⛔ 永不隔着管道下结论——ERR_PNPM 会滚出视野,`| head` 连 `PIPESTATUS` 都改绿(见下节)
- 浏览器验证:Chromium **已预装**——`PLAYWRIGHT_BROWSERS_PATH` 指向 `/opt/pw-browsers`,launch 传
`executablePath: '/opt/pw-browsers/chromium'`。⛔ 永不跑 `playwright install`(出口策略拦它),且
`cdn.playwright.dev` 的 403 不是「没有浏览器」证据——下载被拦不证明产物缺席,先找产物。
Expand DownExpand Up@@ -185,15 +185,15 @@ pin 要防的失效 —— 而不是回退到本行。 -->
且没人会察觉 —— 迟到的 commit 挪动的恰恰是过期的 **ratchet** 读数。复核后任何一次
push,都在新 head 上重跑并集 —— 至少 ratchet 族 —— **然后**才更新报告或 PR 正文。

**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** `EXIT=$?` 跟
`cmd 2>&1 | tail -40` 之后,读到的是 **`tail` 的**状态:`tail` 基本永不失败,绿门禁与红门禁读出
来都是 `0`(实测:一次 typecheck 印着 `Exit status 2`,旁边的 `EXIT` 行写 `0`)。这不只是不可
靠,是**不可证伪**:对两种结局返回同一个值,重跑也翻不出来,却在报告里读作一次测量。三
种安全写法任选:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)·`set -o pipefail`·
`${PIPESTATUS[0]}`。另一半在报告侧:**引用某个门禁结果时,点名它自己印出的判定行**,永不引
裸 `$?` —— 判定行由门禁写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 agent 的 shell 用法
里,没有任何受版本控制的产物看得见它,已判定不可机械化 —— 这两条纪律就是全部的守
**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** 免疫写法
只有一种:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)。两个实测管道假绿,
同样**不可证伪**(红绿都回同一个 0,重跑翻不出来):① `EXIT=$?` 跟在 `cmd 2>&1 | tail -40` 之
后读到的是 **`tail` 的**状态;② `set -o pipefail` 与 `${PIPESTATUS[0]}` 仅当下游读到 EOF 才安全,
`| head -N` 是实测反例:读满即关读端,生产者吃 EPIPE/SIGPIPE 以 0 退出 —— 是管道改了生产者
的退出码,PIPESTATUS 如实上报,`pipefail` 读的也是同一个被改的状态。此陷阱不限于门禁:任何
`cmd | head` 之后读退出码都中招(`git grep`、`node` 皆然);读输出无事,读退出码即假绿。另一半
在报告侧:**引用门禁结果时,点名它自己印出的判定行**,永不引裸 `$?` —— 判定行由门禁
写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 shell 用法里,已判定不可机械化

**两类「跑了却没测到」,都读作 NOT MEASURED,不读作绿、也不读作红。** ① 包的 `typecheck` 可
能 `exclude` 掉 `**/*.test.ts` —— 于是「typecheck 干净」是一句真话,却对你新写的测试文件一个
Expand Down
6 changes: 4 additions & 2 deletions scripts/check-i18n-bundles.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -990,8 +990,10 @@ function reportPrerequisiteNotMet(headline, detail, options = {}) {
`\n\n Fix: ${fix}\n` +
alsoFix.map((l) => ` ${l}\n`).join('') +
`\n${nothingChecked}\n` +
` (Exit code 1 — but piping this gate reports the PIPE's status, so\n` +
` \`pnpm check:i18n | tail -4\` reads green either way. Use \`echo "EXIT=$?"\`.)`,
` (Exit code 1 — capture it BEFORE any pipe: \`pnpm check:i18n > /tmp/i18n.log 2>&1; echo "EXIT=$?"\`.\n` +
` Piped, \`$?\` is the pipe's status, and \`| head -N\` turns even \`\${PIPESTATUS[0]}\`/\`pipefail\` green:\n` +
` \`head\` closes the read end early, so this gate takes EPIPE and exits 0 — the pipe changed the\n` +
` exit code itself. \`| tail\` reads to EOF; \`\${PIPESTATUS[0]}\` after it is the true status.)`,
);
process.exit(1);
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(agents,scripts): PIPESTATUS/pipefail are exit-code-safe only when the downstream reads to EOF by zhuangjianguo · Pull Request #13427 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .claude/agents/os-dev.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,8 +137,8 @@ pin 要防的失效 —— 而不是回退到本行。 -->
double** —— 不新增要 pin 的 double,不动台账。
- 匹配到零个脚本的 `pnpm --filter` 运行**以 0 退出**——什么都没跑,读上去却是通过;objectui
把 typecheck 拼作 `type-check`(连字符),拼错脚本名正好落进这个坑(拼对时依赖闭包没
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,或从 `PIPESTATUS` 读
退出码,⛔ 永不隔着管道 `tail` 下结论——ERR_PNPM 提示会被滚出视野
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,退出码先重定向再捕
,⛔ 永不隔着管道下结论——ERR_PNPM 会滚出视野,`| head` 连 `PIPESTATUS` 都改绿(见下节)
- 浏览器验证:Chromium **已预装**——`PLAYWRIGHT_BROWSERS_PATH` 指向 `/opt/pw-browsers`,launch 传
`executablePath: '/opt/pw-browsers/chromium'`。⛔ 永不跑 `playwright install`(出口策略拦它),且
`cdn.playwright.dev` 的 403 不是「没有浏览器」证据——下载被拦不证明产物缺席,先找产物。
Expand DownExpand Up@@ -185,15 +185,15 @@ pin 要防的失效 —— 而不是回退到本行。 -->
且没人会察觉 —— 迟到的 commit 挪动的恰恰是过期的 **ratchet** 读数。复核后任何一次
push,都在新 head 上重跑并集 —— 至少 ratchet 族 —— **然后**才更新报告或 PR 正文。

**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** `EXIT=$?` 跟
`cmd 2>&1 | tail -40` 之后,读到的是 **`tail` 的**状态:`tail` 基本永不失败,绿门禁与红门禁读出
来都是 `0`(实测:一次 typecheck 印着 `Exit status 2`,旁边的 `EXIT` 行写 `0`)。这不只是不可
靠,是**不可证伪**:对两种结局返回同一个值,重跑也翻不出来,却在报告里读作一次测量。三
种安全写法任选:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)·`set -o pipefail`·
`${PIPESTATUS[0]}`。另一半在报告侧:**引用某个门禁结果时,点名它自己印出的判定行**,永不引
裸 `$?` —— 判定行由门禁写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 agent 的 shell 用法
里,没有任何受版本控制的产物看得见它,已判定不可机械化 —— 这两条纪律就是全部的守
**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** 免疫写法
只有一种:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)。两个实测管道假绿,
同样**不可证伪**(红绿都回同一个 0,重跑翻不出来):① `EXIT=$?` 跟在 `cmd 2>&1 | tail -40` 之
后读到的是 **`tail` 的**状态;② `set -o pipefail` 与 `${PIPESTATUS[0]}` 仅当下游读到 EOF 才安全,
`| head -N` 是实测反例:读满即关读端,生产者吃 EPIPE/SIGPIPE 以 0 退出 —— 是管道改了生产者
的退出码,PIPESTATUS 如实上报,`pipefail` 读的也是同一个被改的状态。此陷阱不限于门禁:任何
`cmd | head` 之后读退出码都中招(`git grep`、`node` 皆然);读输出无事,读退出码即假绿。另一半
在报告侧:**引用门禁结果时,点名它自己印出的判定行**,永不引裸 `$?` —— 判定行由门禁
写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 shell 用法里,已判定不可机械化

**两类「跑了却没测到」,都读作 NOT MEASURED,不读作绿、也不读作红。** ① 包的 `typecheck` 可
能 `exclude` 掉 `**/*.test.ts` —— 于是「typecheck 干净」是一句真话,却对你新写的测试文件一个
Expand Down
6 changes: 4 additions & 2 deletions scripts/check-i18n-bundles.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -990,8 +990,10 @@ function reportPrerequisiteNotMet(headline, detail, options = {}) {
`\n\n Fix: ${fix}\n` +
alsoFix.map((l) => ` ${l}\n`).join('') +
`\n${nothingChecked}\n` +
` (Exit code 1 — but piping this gate reports the PIPE's status, so\n` +
` \`pnpm check:i18n | tail -4\` reads green either way. Use \`echo "EXIT=$?"\`.)`,
` (Exit code 1 — capture it BEFORE any pipe: \`pnpm check:i18n > /tmp/i18n.log 2>&1; echo "EXIT=$?"\`.\n` +
` Piped, \`$?\` is the pipe's status, and \`| head -N\` turns even \`\${PIPESTATUS[0]}\`/\`pipefail\` green:\n` +
` \`head\` closes the read end early, so this gate takes EPIPE and exits 0 — the pipe changed the\n` +
` exit code itself. \`| tail\` reads to EOF; \`\${PIPESTATUS[0]}\` after it is the true status.)`,
);
process.exit(1);
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(agents,scripts): PIPESTATUS/pipefail are exit-code-safe only when the downstream reads to EOF by zhuangjianguo · Pull Request #13427 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .claude/agents/os-dev.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,8 +137,8 @@ pin 要防的失效 —— 而不是回退到本行。 -->
double** —— 不新增要 pin 的 double,不动台账。
- 匹配到零个脚本的 `pnpm --filter` 运行**以 0 退出**——什么都没跑,读上去却是通过;objectui
把 typecheck 拼作 `type-check`(连字符),拼错脚本名正好落进这个坑(拼对时依赖闭包没
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,或从 `PIPESTATUS` 读
退出码,⛔ 永不隔着管道 `tail` 下结论——ERR_PNPM 提示会被滚出视野
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,退出码先重定向再捕
,⛔ 永不隔着管道下结论——ERR_PNPM 会滚出视野,`| head` 连 `PIPESTATUS` 都改绿(见下节)
- 浏览器验证:Chromium **已预装**——`PLAYWRIGHT_BROWSERS_PATH` 指向 `/opt/pw-browsers`,launch 传
`executablePath: '/opt/pw-browsers/chromium'`。⛔ 永不跑 `playwright install`(出口策略拦它),且
`cdn.playwright.dev` 的 403 不是「没有浏览器」证据——下载被拦不证明产物缺席,先找产物。
Expand DownExpand Up@@ -185,15 +185,15 @@ pin 要防的失效 —— 而不是回退到本行。 -->
且没人会察觉 —— 迟到的 commit 挪动的恰恰是过期的 **ratchet** 读数。复核后任何一次
push,都在新 head 上重跑并集 —— 至少 ratchet 族 —— **然后**才更新报告或 PR 正文。

**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** `EXIT=$?` 跟
`cmd 2>&1 | tail -40` 之后,读到的是 **`tail` 的**状态:`tail` 基本永不失败,绿门禁与红门禁读出
来都是 `0`(实测:一次 typecheck 印着 `Exit status 2`,旁边的 `EXIT` 行写 `0`)。这不只是不可
靠,是**不可证伪**:对两种结局返回同一个值,重跑也翻不出来,却在报告里读作一次测量。三
种安全写法任选:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)·`set -o pipefail`·
`${PIPESTATUS[0]}`。另一半在报告侧:**引用某个门禁结果时,点名它自己印出的判定行**,永不引
裸 `$?` —— 判定行由门禁写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 agent 的 shell 用法
里,没有任何受版本控制的产物看得见它,已判定不可机械化 —— 这两条纪律就是全部的守
**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** 免疫写法
只有一种:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)。两个实测管道假绿,
同样**不可证伪**(红绿都回同一个 0,重跑翻不出来):① `EXIT=$?` 跟在 `cmd 2>&1 | tail -40` 之
后读到的是 **`tail` 的**状态;② `set -o pipefail` 与 `${PIPESTATUS[0]}` 仅当下游读到 EOF 才安全,
`| head -N` 是实测反例:读满即关读端,生产者吃 EPIPE/SIGPIPE 以 0 退出 —— 是管道改了生产者
的退出码,PIPESTATUS 如实上报,`pipefail` 读的也是同一个被改的状态。此陷阱不限于门禁:任何
`cmd | head` 之后读退出码都中招(`git grep`、`node` 皆然);读输出无事,读退出码即假绿。另一半
在报告侧:**引用门禁结果时,点名它自己印出的判定行**,永不引裸 `$?` —— 判定行由门禁
写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 shell 用法里,已判定不可机械化

**两类「跑了却没测到」,都读作 NOT MEASURED,不读作绿、也不读作红。** ① 包的 `typecheck` 可
能 `exclude` 掉 `**/*.test.ts` —— 于是「typecheck 干净」是一句真话,却对你新写的测试文件一个
Expand Down
6 changes: 4 additions & 2 deletions scripts/check-i18n-bundles.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -990,8 +990,10 @@ function reportPrerequisiteNotMet(headline, detail, options = {}) {
`\n\n Fix: ${fix}\n` +
alsoFix.map((l) => ` ${l}\n`).join('') +
`\n${nothingChecked}\n` +
` (Exit code 1 — but piping this gate reports the PIPE's status, so\n` +
` \`pnpm check:i18n | tail -4\` reads green either way. Use \`echo "EXIT=$?"\`.)`,
` (Exit code 1 — capture it BEFORE any pipe: \`pnpm check:i18n > /tmp/i18n.log 2>&1; echo "EXIT=$?"\`.\n` +
` Piped, \`$?\` is the pipe's status, and \`| head -N\` turns even \`\${PIPESTATUS[0]}\`/\`pipefail\` green:\n` +
` \`head\` closes the read end early, so this gate takes EPIPE and exits 0 — the pipe changed the\n` +
` exit code itself. \`| tail\` reads to EOF; \`\${PIPESTATUS[0]}\` after it is the true status.)`,
);
process.exit(1);
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(agents,scripts): PIPESTATUS/pipefail are exit-code-safe only when the downstream reads to EOF by zhuangjianguo · Pull Request #13427 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .claude/agents/os-dev.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,8 +137,8 @@ pin 要防的失效 —— 而不是回退到本行。 -->
double** —— 不新增要 pin 的 double,不动台账。
- 匹配到零个脚本的 `pnpm --filter` 运行**以 0 退出**——什么都没跑,读上去却是通过;objectui
把 typecheck 拼作 `type-check`(连字符),拼错脚本名正好落进这个坑(拼对时依赖闭包没
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,或从 `PIPESTATUS` 读
退出码,⛔ 永不隔着管道 `tail` 下结论——ERR_PNPM 提示会被滚出视野
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,退出码先重定向再捕
,⛔ 永不隔着管道下结论——ERR_PNPM 会滚出视野,`| head` 连 `PIPESTATUS` 都改绿(见下节)
- 浏览器验证:Chromium **已预装**——`PLAYWRIGHT_BROWSERS_PATH` 指向 `/opt/pw-browsers`,launch 传
`executablePath: '/opt/pw-browsers/chromium'`。⛔ 永不跑 `playwright install`(出口策略拦它),且
`cdn.playwright.dev` 的 403 不是「没有浏览器」证据——下载被拦不证明产物缺席,先找产物。
Expand DownExpand Up@@ -185,15 +185,15 @@ pin 要防的失效 —— 而不是回退到本行。 -->
且没人会察觉 —— 迟到的 commit 挪动的恰恰是过期的 **ratchet** 读数。复核后任何一次
push,都在新 head 上重跑并集 —— 至少 ratchet 族 —— **然后**才更新报告或 PR 正文。

**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** `EXIT=$?` 跟
`cmd 2>&1 | tail -40` 之后,读到的是 **`tail` 的**状态:`tail` 基本永不失败,绿门禁与红门禁读出
来都是 `0`(实测:一次 typecheck 印着 `Exit status 2`,旁边的 `EXIT` 行写 `0`)。这不只是不可
靠,是**不可证伪**:对两种结局返回同一个值,重跑也翻不出来,却在报告里读作一次测量。三
种安全写法任选:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)·`set -o pipefail`·
`${PIPESTATUS[0]}`。另一半在报告侧:**引用某个门禁结果时,点名它自己印出的判定行**,永不引
裸 `$?` —— 判定行由门禁写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 agent 的 shell 用法
里,没有任何受版本控制的产物看得见它,已判定不可机械化 —— 这两条纪律就是全部的守
**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** 免疫写法
只有一种:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)。两个实测管道假绿,
同样**不可证伪**(红绿都回同一个 0,重跑翻不出来):① `EXIT=$?` 跟在 `cmd 2>&1 | tail -40` 之
后读到的是 **`tail` 的**状态;② `set -o pipefail` 与 `${PIPESTATUS[0]}` 仅当下游读到 EOF 才安全,
`| head -N` 是实测反例:读满即关读端,生产者吃 EPIPE/SIGPIPE 以 0 退出 —— 是管道改了生产者
的退出码,PIPESTATUS 如实上报,`pipefail` 读的也是同一个被改的状态。此陷阱不限于门禁:任何
`cmd | head` 之后读退出码都中招(`git grep`、`node` 皆然);读输出无事,读退出码即假绿。另一半
在报告侧:**引用门禁结果时,点名它自己印出的判定行**,永不引裸 `$?` —— 判定行由门禁
写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 shell 用法里,已判定不可机械化

**两类「跑了却没测到」,都读作 NOT MEASURED,不读作绿、也不读作红。** ① 包的 `typecheck` 可
能 `exclude` 掉 `**/*.test.ts` —— 于是「typecheck 干净」是一句真话,却对你新写的测试文件一个
Expand Down
6 changes: 4 additions & 2 deletions scripts/check-i18n-bundles.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -990,8 +990,10 @@ function reportPrerequisiteNotMet(headline, detail, options = {}) {
`\n\n Fix: ${fix}\n` +
alsoFix.map((l) => ` ${l}\n`).join('') +
`\n${nothingChecked}\n` +
` (Exit code 1 — but piping this gate reports the PIPE's status, so\n` +
` \`pnpm check:i18n | tail -4\` reads green either way. Use \`echo "EXIT=$?"\`.)`,
` (Exit code 1 — capture it BEFORE any pipe: \`pnpm check:i18n > /tmp/i18n.log 2>&1; echo "EXIT=$?"\`.\n` +
` Piped, \`$?\` is the pipe's status, and \`| head -N\` turns even \`\${PIPESTATUS[0]}\`/\`pipefail\` green:\n` +
` \`head\` closes the read end early, so this gate takes EPIPE and exits 0 — the pipe changed the\n` +
` exit code itself. \`| tail\` reads to EOF; \`\${PIPESTATUS[0]}\` after it is the true status.)`,
);
process.exit(1);
}
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix(agents,scripts): PIPESTATUS/pipefail are exit-code-safe only when the downstream reads to EOF by zhuangjianguo · Pull Request #13427 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .claude/agents/os-dev.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,8 +137,8 @@ pin 要防的失效 —— 而不是回退到本行。 -->
double** —— 不新增要 pin 的 double,不动台账。
- 匹配到零个脚本的 `pnpm --filter` 运行**以 0 退出**——什么都没跑,读上去却是通过;objectui
把 typecheck 拼作 `type-check`(连字符),拼错脚本名正好落进这个坑(拼对时依赖闭包没
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,或从 `PIPESTATUS` 读
退出码,⛔ 永不隔着管道 `tail` 下结论——ERR_PNPM 提示会被滚出视野
build 它本会转红,零匹配却静默变绿)。核对输出里确实回显了脚本名,退出码先重定向再捕
,⛔ 永不隔着管道下结论——ERR_PNPM 会滚出视野,`| head` 连 `PIPESTATUS` 都改绿(见下节)
- 浏览器验证:Chromium **已预装**——`PLAYWRIGHT_BROWSERS_PATH` 指向 `/opt/pw-browsers`,launch 传
`executablePath: '/opt/pw-browsers/chromium'`。⛔ 永不跑 `playwright install`(出口策略拦它),且
`cdn.playwright.dev` 的 403 不是「没有浏览器」证据——下载被拦不证明产物缺席,先找产物。
Expand DownExpand Up@@ -185,15 +185,15 @@ pin 要防的失效 —— 而不是回退到本行。 -->
且没人会察觉 —— 迟到的 commit 挪动的恰恰是过期的 **ratchet** 读数。复核后任何一次
push,都在新 head 上重跑并集 —— 至少 ratchet 族 —— **然后**才更新报告或 PR 正文。

**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** `EXIT=$?` 跟
`cmd 2>&1 | tail -40` 之后,读到的是 **`tail` 的**状态:`tail` 基本永不失败,绿门禁与红门禁读出
来都是 `0`(实测:一次 typecheck 印着 `Exit status 2`,旁边的 `EXIT` 行写 `0`)。这不只是不可
靠,是**不可证伪**:对两种结局返回同一个值,重跑也翻不出来,却在报告里读作一次测量。三
种安全写法任选:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)·`set -o pipefail`·
`${PIPESTATUS[0]}`。另一半在报告侧:**引用某个门禁结果时,点名它自己印出的判定行**,永不引
裸 `$?` —— 判定行由门禁写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 agent 的 shell 用法
里,没有任何受版本控制的产物看得见它,已判定不可机械化 —— 这两条纪律就是全部的守
**门禁结果的读法:退出码在任何管道之前捕获,报告里引门禁自己印的判定行。** 免疫写法
只有一种:先重定向再捕获(`cmd > /tmp/out 2>&1; EXIT=$?; tail -40 /tmp/out`)。两个实测管道假绿,
同样**不可证伪**(红绿都回同一个 0,重跑翻不出来):① `EXIT=$?` 跟在 `cmd 2>&1 | tail -40` 之
后读到的是 **`tail` 的**状态;② `set -o pipefail` 与 `${PIPESTATUS[0]}` 仅当下游读到 EOF 才安全,
`| head -N` 是实测反例:读满即关读端,生产者吃 EPIPE/SIGPIPE 以 0 退出 —— 是管道改了生产者
的退出码,PIPESTATUS 如实上报,`pipefail` 读的也是同一个被改的状态。此陷阱不限于门禁:任何
`cmd | head` 之后读退出码都中招(`git grep`、`node` 皆然);读输出无事,读退出码即假绿。另一半
在报告侧:**引用门禁结果时,点名它自己印出的判定行**,永不引裸 `$?` —— 判定行由门禁
写,`$?` 由你的管道写。⛔ 别等机械强制:陷阱在 shell 用法里,已判定不可机械化

**两类「跑了却没测到」,都读作 NOT MEASURED,不读作绿、也不读作红。** ① 包的 `typecheck` 可
能 `exclude` 掉 `**/*.test.ts` —— 于是「typecheck 干净」是一句真话,却对你新写的测试文件一个
Expand Down
6 changes: 4 additions & 2 deletions scripts/check-i18n-bundles.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -990,8 +990,10 @@ function reportPrerequisiteNotMet(headline, detail, options = {}) {
`\n\n Fix: ${fix}\n` +
alsoFix.map((l) => ` ${l}\n`).join('') +
`\n${nothingChecked}\n` +
` (Exit code 1 — but piping this gate reports the PIPE's status, so\n` +
` \`pnpm check:i18n | tail -4\` reads green either way. Use \`echo "EXIT=$?"\`.)`,
` (Exit code 1 — capture it BEFORE any pipe: \`pnpm check:i18n > /tmp/i18n.log 2>&1; echo "EXIT=$?"\`.\n` +
` Piped, \`$?\` is the pipe's status, and \`| head -N\` turns even \`\${PIPESTATUS[0]}\`/\`pipefail\` green:\n` +
` \`head\` closes the read end early, so this gate takes EPIPE and exits 0 — the pipe changed the\n` +
` exit code itself. \`| tail\` reads to EOF; \`\${PIPESTATUS[0]}\` after it is the true status.)`,
);
process.exit(1);
}
Expand Down
Loading