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
25 changes: 25 additions & 0 deletions .changeset/6208-worktree-recipe-fetch-base.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
---
---

Instruction-file and PreToolUse-hook prose only: no published package's `src/` changed, so
nothing ships.

The documented worktree recipe branched off the **local** `main` ref, which nothing in the
recipe or its surrounding prose fetches. A worktree created by following it literally starts
as far back as whoever last happened to update that ref — and on a long-lived shared
checkout, nobody has a reason to. `origin/main` alone would carry the same defect one layer
down (it too is a local ref only a fetch moves), so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base:

```
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Four sites repaired — `CLAUDE.md`, `AGENTS.md` §9 多 agent 协作纪律, and the recipe both
worktree guards print when they block an edit (`.claude/hooks/guard-main-checkout.sh`,
`.claude/hooks/guard-main-checkout-bash.sh`), which is the copy an agent is most likely to
run verbatim. The two `-cmp` comparison-tree lines are unchanged: they take an explicit ref
from the caller and are correct as written.

Ports the repair landed upstream in objectstack#11934 (objectstack#11540); this repo's copy
was deliberately left to this card. Net ±0 lines on every file touched.
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout-bash.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -541,7 +541,7 @@ only, so the identical edit expressed as a shell command used to slip through in
its HEAD switched and its tree reset under you, clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you need a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run the command there

Always fine, no flag needed:
Expand Down
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,7 @@ This repo is edited by multiple agents at once — the shared checkout gets its
switched and tree reset under you, silently clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you must be in a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run your edits there

This guard checks the edited file's OWN repo, so sibling repos are covered too.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -231,7 +231,7 @@ AGENTS.md 的「只跑受影响的包」指的是**用上面的路径过滤缩
本仓库有**多个 agent 并行**修改 —— 分支会被切换、共享文件会在你工作时被改动(正常现象,不是 bug):

- **只改你任务需要的文件**;别去"修"无关的 diff、回退或别人的在途编辑,也别管整棵工作树。
- **必须一个任务一个 git worktree**(`git worktree add ../objectui-<task> -b <branch> main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **必须一个任务一个 git worktree**(`git fetch origin main && git worktree add ../objectui-<task> -b <branch> origin/main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **绝不 `git stash` —— stash 栈不在上一条的 worktree 隔离范围内。** `git stash` 把栈存在**共享 `.git` 目录**里的 `refs/stash`,**每个 worktree 共用同一个 LIFO 栈**:上一条的物理隔离**不覆盖它**。两个 agent 各自在自己的 worktree 里 stash,push/pop 的是同一个栈 —— 你的 `pop` 取回的是对方刚压进去的改动,你自己的改动留在栈上等着被对方取走;而 `pop` **报成功**,唯一的症状是别人的文件出现在你的 `git status` 里,随后一次 `git add -A` 就把对方的在途工作合进了你的 PR。不是假想:objectui#3430 两个并行 agent 在反向验证中间踩实,双方在途改动都丢了(只能作为 unreachable commit 捞回)。替代做法只有下面这些 —— 都不碰共享状态,都在你自己的 worktree 内,且**首选先 commit 再还原**(上面反向验证那条已把它定为标准写法):

```bash
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,7 +13,7 @@ shared checkout is NOT enough** — it still gets switched under you. You MUST b
**dedicated per-task worktree**:

```
git worktree add ../<repo>-<task> -b <branch> main && cd ../<repo>-<task> && pnpm install
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Make all edits there, **one worktree per repo** a task spans. A PreToolUse hook
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" + '
Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · 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
25 changes: 25 additions & 0 deletions .changeset/6208-worktree-recipe-fetch-base.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
---
---

Instruction-file and PreToolUse-hook prose only: no published package's `src/` changed, so
nothing ships.

The documented worktree recipe branched off the **local** `main` ref, which nothing in the
recipe or its surrounding prose fetches. A worktree created by following it literally starts
as far back as whoever last happened to update that ref — and on a long-lived shared
checkout, nobody has a reason to. `origin/main` alone would carry the same defect one layer
down (it too is a local ref only a fetch moves), so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base:

```
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Four sites repaired — `CLAUDE.md`, `AGENTS.md` §9 多 agent 协作纪律, and the recipe both
worktree guards print when they block an edit (`.claude/hooks/guard-main-checkout.sh`,
`.claude/hooks/guard-main-checkout-bash.sh`), which is the copy an agent is most likely to
run verbatim. The two `-cmp` comparison-tree lines are unchanged: they take an explicit ref
from the caller and are correct as written.

Ports the repair landed upstream in objectstack#11934 (objectstack#11540); this repo's copy
was deliberately left to this card. Net ±0 lines on every file touched.
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout-bash.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -541,7 +541,7 @@ only, so the identical edit expressed as a shell command used to slip through in
its HEAD switched and its tree reset under you, clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you need a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run the command there

Always fine, no flag needed:
Expand Down
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,7 @@ This repo is edited by multiple agents at once — the shared checkout gets its
switched and tree reset under you, silently clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you must be in a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run your edits there

This guard checks the edited file's OWN repo, so sibling repos are covered too.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -231,7 +231,7 @@ AGENTS.md 的「只跑受影响的包」指的是**用上面的路径过滤缩
本仓库有**多个 agent 并行**修改 —— 分支会被切换、共享文件会在你工作时被改动(正常现象,不是 bug):

- **只改你任务需要的文件**;别去"修"无关的 diff、回退或别人的在途编辑,也别管整棵工作树。
- **必须一个任务一个 git worktree**(`git worktree add ../objectui-<task> -b <branch> main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **必须一个任务一个 git worktree**(`git fetch origin main && git worktree add ../objectui-<task> -b <branch> origin/main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **绝不 `git stash` —— stash 栈不在上一条的 worktree 隔离范围内。** `git stash` 把栈存在**共享 `.git` 目录**里的 `refs/stash`,**每个 worktree 共用同一个 LIFO 栈**:上一条的物理隔离**不覆盖它**。两个 agent 各自在自己的 worktree 里 stash,push/pop 的是同一个栈 —— 你的 `pop` 取回的是对方刚压进去的改动,你自己的改动留在栈上等着被对方取走;而 `pop` **报成功**,唯一的症状是别人的文件出现在你的 `git status` 里,随后一次 `git add -A` 就把对方的在途工作合进了你的 PR。不是假想:objectui#3430 两个并行 agent 在反向验证中间踩实,双方在途改动都丢了(只能作为 unreachable commit 捞回)。替代做法只有下面这些 —— 都不碰共享状态,都在你自己的 worktree 内,且**首选先 commit 再还原**(上面反向验证那条已把它定为标准写法):

```bash
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,7 +13,7 @@ shared checkout is NOT enough** — it still gets switched under you. You MUST b
**dedicated per-task worktree**:

```
git worktree add ../<repo>-<task> -b <branch> main && cd ../<repo>-<task> && pnpm install
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Make all edits there, **one worktree per repo** a task spans. A PreToolUse hook
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('^' + ".*" + ' Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · 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
25 changes: 25 additions & 0 deletions .changeset/6208-worktree-recipe-fetch-base.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
---
---

Instruction-file and PreToolUse-hook prose only: no published package's `src/` changed, so
nothing ships.

The documented worktree recipe branched off the **local** `main` ref, which nothing in the
recipe or its surrounding prose fetches. A worktree created by following it literally starts
as far back as whoever last happened to update that ref — and on a long-lived shared
checkout, nobody has a reason to. `origin/main` alone would carry the same defect one layer
down (it too is a local ref only a fetch moves), so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base:

```
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Four sites repaired — `CLAUDE.md`, `AGENTS.md` §9 多 agent 协作纪律, and the recipe both
worktree guards print when they block an edit (`.claude/hooks/guard-main-checkout.sh`,
`.claude/hooks/guard-main-checkout-bash.sh`), which is the copy an agent is most likely to
run verbatim. The two `-cmp` comparison-tree lines are unchanged: they take an explicit ref
from the caller and are correct as written.

Ports the repair landed upstream in objectstack#11934 (objectstack#11540); this repo's copy
was deliberately left to this card. Net ±0 lines on every file touched.
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout-bash.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -541,7 +541,7 @@ only, so the identical edit expressed as a shell command used to slip through in
its HEAD switched and its tree reset under you, clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you need a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run the command there

Always fine, no flag needed:
Expand Down
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,7 @@ This repo is edited by multiple agents at once — the shared checkout gets its
switched and tree reset under you, silently clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you must be in a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run your edits there

This guard checks the edited file's OWN repo, so sibling repos are covered too.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -231,7 +231,7 @@ AGENTS.md 的「只跑受影响的包」指的是**用上面的路径过滤缩
本仓库有**多个 agent 并行**修改 —— 分支会被切换、共享文件会在你工作时被改动(正常现象,不是 bug):

- **只改你任务需要的文件**;别去"修"无关的 diff、回退或别人的在途编辑,也别管整棵工作树。
- **必须一个任务一个 git worktree**(`git worktree add ../objectui-<task> -b <branch> main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **必须一个任务一个 git worktree**(`git fetch origin main && git worktree add ../objectui-<task> -b <branch> origin/main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **绝不 `git stash` —— stash 栈不在上一条的 worktree 隔离范围内。** `git stash` 把栈存在**共享 `.git` 目录**里的 `refs/stash`,**每个 worktree 共用同一个 LIFO 栈**:上一条的物理隔离**不覆盖它**。两个 agent 各自在自己的 worktree 里 stash,push/pop 的是同一个栈 —— 你的 `pop` 取回的是对方刚压进去的改动,你自己的改动留在栈上等着被对方取走;而 `pop` **报成功**,唯一的症状是别人的文件出现在你的 `git status` 里,随后一次 `git add -A` 就把对方的在途工作合进了你的 PR。不是假想:objectui#3430 两个并行 agent 在反向验证中间踩实,双方在途改动都丢了(只能作为 unreachable commit 捞回)。替代做法只有下面这些 —— 都不碰共享状态,都在你自己的 worktree 内,且**首选先 commit 再还原**(上面反向验证那条已把它定为标准写法):

```bash
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,7 +13,7 @@ shared checkout is NOT enough** — it still gets switched under you. You MUST b
**dedicated per-task worktree**:

```
git worktree add ../<repo>-<task> -b <branch> main && cd ../<repo>-<task> && pnpm install
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Make all edits there, **one worktree per repo** a task spans. A PreToolUse hook
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('^' + ".*" + ' Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · 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
25 changes: 25 additions & 0 deletions .changeset/6208-worktree-recipe-fetch-base.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
---
---

Instruction-file and PreToolUse-hook prose only: no published package's `src/` changed, so
nothing ships.

The documented worktree recipe branched off the **local** `main` ref, which nothing in the
recipe or its surrounding prose fetches. A worktree created by following it literally starts
as far back as whoever last happened to update that ref — and on a long-lived shared
checkout, nobody has a reason to. `origin/main` alone would carry the same defect one layer
down (it too is a local ref only a fetch moves), so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base:

```
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Four sites repaired — `CLAUDE.md`, `AGENTS.md` §9 多 agent 协作纪律, and the recipe both
worktree guards print when they block an edit (`.claude/hooks/guard-main-checkout.sh`,
`.claude/hooks/guard-main-checkout-bash.sh`), which is the copy an agent is most likely to
run verbatim. The two `-cmp` comparison-tree lines are unchanged: they take an explicit ref
from the caller and are correct as written.

Ports the repair landed upstream in objectstack#11934 (objectstack#11540); this repo's copy
was deliberately left to this card. Net ±0 lines on every file touched.
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout-bash.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -541,7 +541,7 @@ only, so the identical edit expressed as a shell command used to slip through in
its HEAD switched and its tree reset under you, clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you need a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run the command there

Always fine, no flag needed:
Expand Down
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,7 @@ This repo is edited by multiple agents at once — the shared checkout gets its
switched and tree reset under you, silently clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you must be in a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run your edits there

This guard checks the edited file's OWN repo, so sibling repos are covered too.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -231,7 +231,7 @@ AGENTS.md 的「只跑受影响的包」指的是**用上面的路径过滤缩
本仓库有**多个 agent 并行**修改 —— 分支会被切换、共享文件会在你工作时被改动(正常现象,不是 bug):

- **只改你任务需要的文件**;别去"修"无关的 diff、回退或别人的在途编辑,也别管整棵工作树。
- **必须一个任务一个 git worktree**(`git worktree add ../objectui-<task> -b <branch> main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **必须一个任务一个 git worktree**(`git fetch origin main && git worktree add ../objectui-<task> -b <branch> origin/main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **绝不 `git stash` —— stash 栈不在上一条的 worktree 隔离范围内。** `git stash` 把栈存在**共享 `.git` 目录**里的 `refs/stash`,**每个 worktree 共用同一个 LIFO 栈**:上一条的物理隔离**不覆盖它**。两个 agent 各自在自己的 worktree 里 stash,push/pop 的是同一个栈 —— 你的 `pop` 取回的是对方刚压进去的改动,你自己的改动留在栈上等着被对方取走;而 `pop` **报成功**,唯一的症状是别人的文件出现在你的 `git status` 里,随后一次 `git add -A` 就把对方的在途工作合进了你的 PR。不是假想:objectui#3430 两个并行 agent 在反向验证中间踩实,双方在途改动都丢了(只能作为 unreachable commit 捞回)。替代做法只有下面这些 —— 都不碰共享状态,都在你自己的 worktree 内,且**首选先 commit 再还原**(上面反向验证那条已把它定为标准写法):

```bash
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,7 +13,7 @@ shared checkout is NOT enough** — it still gets switched under you. You MUST b
**dedicated per-task worktree**:

```
git worktree add ../<repo>-<task> -b <branch> main && cd ../<repo>-<task> && pnpm install
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Make all edits there, **one worktree per repo** a task spans. A PreToolUse hook
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" + ' Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · 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
25 changes: 25 additions & 0 deletions .changeset/6208-worktree-recipe-fetch-base.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
---
---

Instruction-file and PreToolUse-hook prose only: no published package's `src/` changed, so
nothing ships.

The documented worktree recipe branched off the **local** `main` ref, which nothing in the
recipe or its surrounding prose fetches. A worktree created by following it literally starts
as far back as whoever last happened to update that ref — and on a long-lived shared
checkout, nobody has a reason to. `origin/main` alone would carry the same defect one layer
down (it too is a local ref only a fetch moves), so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base:

```
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Four sites repaired — `CLAUDE.md`, `AGENTS.md` §9 多 agent 协作纪律, and the recipe both
worktree guards print when they block an edit (`.claude/hooks/guard-main-checkout.sh`,
`.claude/hooks/guard-main-checkout-bash.sh`), which is the copy an agent is most likely to
run verbatim. The two `-cmp` comparison-tree lines are unchanged: they take an explicit ref
from the caller and are correct as written.

Ports the repair landed upstream in objectstack#11934 (objectstack#11540); this repo's copy
was deliberately left to this card. Net ±0 lines on every file touched.
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout-bash.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -541,7 +541,7 @@ only, so the identical edit expressed as a shell command used to slip through in
its HEAD switched and its tree reset under you, clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you need a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run the command there

Always fine, no flag needed:
Expand Down
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,7 @@ This repo is edited by multiple agents at once — the shared checkout gets its
switched and tree reset under you, silently clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you must be in a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run your edits there

This guard checks the edited file's OWN repo, so sibling repos are covered too.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -231,7 +231,7 @@ AGENTS.md 的「只跑受影响的包」指的是**用上面的路径过滤缩
本仓库有**多个 agent 并行**修改 —— 分支会被切换、共享文件会在你工作时被改动(正常现象,不是 bug):

- **只改你任务需要的文件**;别去"修"无关的 diff、回退或别人的在途编辑,也别管整棵工作树。
- **必须一个任务一个 git worktree**(`git worktree add ../objectui-<task> -b <branch> main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **必须一个任务一个 git worktree**(`git fetch origin main && git worktree add ../objectui-<task> -b <branch> origin/main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **绝不 `git stash` —— stash 栈不在上一条的 worktree 隔离范围内。** `git stash` 把栈存在**共享 `.git` 目录**里的 `refs/stash`,**每个 worktree 共用同一个 LIFO 栈**:上一条的物理隔离**不覆盖它**。两个 agent 各自在自己的 worktree 里 stash,push/pop 的是同一个栈 —— 你的 `pop` 取回的是对方刚压进去的改动,你自己的改动留在栈上等着被对方取走;而 `pop` **报成功**,唯一的症状是别人的文件出现在你的 `git status` 里,随后一次 `git add -A` 就把对方的在途工作合进了你的 PR。不是假想:objectui#3430 两个并行 agent 在反向验证中间踩实,双方在途改动都丢了(只能作为 unreachable commit 捞回)。替代做法只有下面这些 —— 都不碰共享状态,都在你自己的 worktree 内,且**首选先 commit 再还原**(上面反向验证那条已把它定为标准写法):

```bash
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,7 +13,7 @@ shared checkout is NOT enough** — it still gets switched under you. You MUST b
**dedicated per-task worktree**:

```
git worktree add ../<repo>-<task> -b <branch> main && cd ../<repo>-<task> && pnpm install
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Make all edits there, **one worktree per repo** a task spans. A PreToolUse hook
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('^' + ".*" + ' Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · 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
25 changes: 25 additions & 0 deletions .changeset/6208-worktree-recipe-fetch-base.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
---
---

Instruction-file and PreToolUse-hook prose only: no published package's `src/` changed, so
nothing ships.

The documented worktree recipe branched off the **local** `main` ref, which nothing in the
recipe or its surrounding prose fetches. A worktree created by following it literally starts
as far back as whoever last happened to update that ref — and on a long-lived shared
checkout, nobody has a reason to. `origin/main` alone would carry the same defect one layer
down (it too is a local ref only a fetch moves), so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base:

```
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Four sites repaired — `CLAUDE.md`, `AGENTS.md` §9 多 agent 协作纪律, and the recipe both
worktree guards print when they block an edit (`.claude/hooks/guard-main-checkout.sh`,
`.claude/hooks/guard-main-checkout-bash.sh`), which is the copy an agent is most likely to
run verbatim. The two `-cmp` comparison-tree lines are unchanged: they take an explicit ref
from the caller and are correct as written.

Ports the repair landed upstream in objectstack#11934 (objectstack#11540); this repo's copy
was deliberately left to this card. Net ±0 lines on every file touched.
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout-bash.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -541,7 +541,7 @@ only, so the identical edit expressed as a shell command used to slip through in
its HEAD switched and its tree reset under you, clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you need a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run the command there

Always fine, no flag needed:
Expand Down
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,7 @@ This repo is edited by multiple agents at once — the shared checkout gets its
switched and tree reset under you, silently clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you must be in a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run your edits there

This guard checks the edited file's OWN repo, so sibling repos are covered too.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -231,7 +231,7 @@ AGENTS.md 的「只跑受影响的包」指的是**用上面的路径过滤缩
本仓库有**多个 agent 并行**修改 —— 分支会被切换、共享文件会在你工作时被改动(正常现象,不是 bug):

- **只改你任务需要的文件**;别去"修"无关的 diff、回退或别人的在途编辑,也别管整棵工作树。
- **必须一个任务一个 git worktree**(`git worktree add ../objectui-<task> -b <branch> main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **必须一个任务一个 git worktree**(`git fetch origin main && git worktree add ../objectui-<task> -b <branch> origin/main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **绝不 `git stash` —— stash 栈不在上一条的 worktree 隔离范围内。** `git stash` 把栈存在**共享 `.git` 目录**里的 `refs/stash`,**每个 worktree 共用同一个 LIFO 栈**:上一条的物理隔离**不覆盖它**。两个 agent 各自在自己的 worktree 里 stash,push/pop 的是同一个栈 —— 你的 `pop` 取回的是对方刚压进去的改动,你自己的改动留在栈上等着被对方取走;而 `pop` **报成功**,唯一的症状是别人的文件出现在你的 `git status` 里,随后一次 `git add -A` 就把对方的在途工作合进了你的 PR。不是假想:objectui#3430 两个并行 agent 在反向验证中间踩实,双方在途改动都丢了(只能作为 unreachable commit 捞回)。替代做法只有下面这些 —— 都不碰共享状态,都在你自己的 worktree 内,且**首选先 commit 再还原**(上面反向验证那条已把它定为标准写法):

```bash
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,7 +13,7 @@ shared checkout is NOT enough** — it still gets switched under you. You MUST b
**dedicated per-task worktree**:

```
git worktree add ../<repo>-<task> -b <branch> main && cd ../<repo>-<task> && pnpm install
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Make all edits there, **one worktree per repo** a task spans. A PreToolUse hook
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('^' + ".*" + ' Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · 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
25 changes: 25 additions & 0 deletions .changeset/6208-worktree-recipe-fetch-base.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
---
---

Instruction-file and PreToolUse-hook prose only: no published package's `src/` changed, so
nothing ships.

The documented worktree recipe branched off the **local** `main` ref, which nothing in the
recipe or its surrounding prose fetches. A worktree created by following it literally starts
as far back as whoever last happened to update that ref — and on a long-lived shared
checkout, nobody has a reason to. `origin/main` alone would carry the same defect one layer
down (it too is a local ref only a fetch moves), so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base:

```
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Four sites repaired — `CLAUDE.md`, `AGENTS.md` §9 多 agent 协作纪律, and the recipe both
worktree guards print when they block an edit (`.claude/hooks/guard-main-checkout.sh`,
`.claude/hooks/guard-main-checkout-bash.sh`), which is the copy an agent is most likely to
run verbatim. The two `-cmp` comparison-tree lines are unchanged: they take an explicit ref
from the caller and are correct as written.

Ports the repair landed upstream in objectstack#11934 (objectstack#11540); this repo's copy
was deliberately left to this card. Net ±0 lines on every file touched.
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout-bash.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -541,7 +541,7 @@ only, so the identical edit expressed as a shell command used to slip through in
its HEAD switched and its tree reset under you, clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you need a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run the command there

Always fine, no flag needed:
Expand Down
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,7 @@ This repo is edited by multiple agents at once — the shared checkout gets its
switched and tree reset under you, silently clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you must be in a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run your edits there

This guard checks the edited file's OWN repo, so sibling repos are covered too.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -231,7 +231,7 @@ AGENTS.md 的「只跑受影响的包」指的是**用上面的路径过滤缩
本仓库有**多个 agent 并行**修改 —— 分支会被切换、共享文件会在你工作时被改动(正常现象,不是 bug):

- **只改你任务需要的文件**;别去"修"无关的 diff、回退或别人的在途编辑,也别管整棵工作树。
- **必须一个任务一个 git worktree**(`git worktree add ../objectui-<task> -b <branch> main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **必须一个任务一个 git worktree**(`git fetch origin main && git worktree add ../objectui-<task> -b <branch> origin/main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **绝不 `git stash` —— stash 栈不在上一条的 worktree 隔离范围内。** `git stash` 把栈存在**共享 `.git` 目录**里的 `refs/stash`,**每个 worktree 共用同一个 LIFO 栈**:上一条的物理隔离**不覆盖它**。两个 agent 各自在自己的 worktree 里 stash,push/pop 的是同一个栈 —— 你的 `pop` 取回的是对方刚压进去的改动,你自己的改动留在栈上等着被对方取走;而 `pop` **报成功**,唯一的症状是别人的文件出现在你的 `git status` 里,随后一次 `git add -A` 就把对方的在途工作合进了你的 PR。不是假想:objectui#3430 两个并行 agent 在反向验证中间踩实,双方在途改动都丢了(只能作为 unreachable commit 捞回)。替代做法只有下面这些 —— 都不碰共享状态,都在你自己的 worktree 内,且**首选先 commit 再还原**(上面反向验证那条已把它定为标准写法):

```bash
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,7 +13,7 @@ shared checkout is NOT enough** — it still gets switched under you. You MUST b
**dedicated per-task worktree**:

```
git worktree add ../<repo>-<task> -b <branch> main && cd ../<repo>-<task> && pnpm install
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Make all edits there, **one worktree per repo** a task spans. A PreToolUse hook
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); } })(); })(); Base the worktree recipe on a fetched origin/main by os-warren · Pull Request #6449 · objectstack-ai/objectui · 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
25 changes: 25 additions & 0 deletions .changeset/6208-worktree-recipe-fetch-base.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
---
---

Instruction-file and PreToolUse-hook prose only: no published package's `src/` changed, so
nothing ships.

The documented worktree recipe branched off the **local** `main` ref, which nothing in the
recipe or its surrounding prose fetches. A worktree created by following it literally starts
as far back as whoever last happened to update that ref — and on a long-lived shared
checkout, nobody has a reason to. `origin/main` alone would carry the same defect one layer
down (it too is a local ref only a fetch moves), so each in-scope site now begins with an
explicit `git fetch origin main &&` and names `origin/main` as the base:

```
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Four sites repaired — `CLAUDE.md`, `AGENTS.md` §9 多 agent 协作纪律, and the recipe both
worktree guards print when they block an edit (`.claude/hooks/guard-main-checkout.sh`,
`.claude/hooks/guard-main-checkout-bash.sh`), which is the copy an agent is most likely to
run verbatim. The two `-cmp` comparison-tree lines are unchanged: they take an explicit ref
from the caller and are correct as written.

Ports the repair landed upstream in objectstack#11934 (objectstack#11540); this repo's copy
was deliberately left to this card. Net ±0 lines on every file touched.
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout-bash.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -541,7 +541,7 @@ only, so the identical edit expressed as a shell command used to slip through in
its HEAD switched and its tree reset under you, clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you need a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run the command there

Always fine, no flag needed:
Expand Down
2 changes: 1 addition & 1 deletion .claude/hooks/guard-main-checkout.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,7 +54,7 @@ This repo is edited by multiple agents at once — the shared checkout gets its
switched and tree reset under you, silently clobbering uncommitted work. A feature
branch on the shared checkout is NOT enough; you must be in a dedicated worktree:

git worktree add ../${name}-<task> -b <branch> main
git fetch origin main && git worktree add ../${name}-<task> -b <branch> origin/main
cd ../${name}-<task> && pnpm install # then re-run your edits there

This guard checks the edited file's OWN repo, so sibling repos are covered too.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -231,7 +231,7 @@ AGENTS.md 的「只跑受影响的包」指的是**用上面的路径过滤缩
本仓库有**多个 agent 并行**修改 —— 分支会被切换、共享文件会在你工作时被改动(正常现象,不是 bug):

- **只改你任务需要的文件**;别去"修"无关的 diff、回退或别人的在途编辑,也别管整棵工作树。
- **必须一个任务一个 git worktree**(`git worktree add ../objectui-<task> -b <branch> main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **必须一个任务一个 git worktree**(`git fetch origin main && git worktree add ../objectui-<task> -b <branch> origin/main`,新树里跑 `pnpm install`)做物理隔离 —— 这是强制而非「首选」。共享的 `main` checkout **不是**可用退路:HEAD 会被别的 agent 切换、你刚写的文件会在操作中途被 reset 掉。一个 **PreToolUse 钩子**(`.claude/hooks/guard-main-checkout.sh`)**强制**此规则:除非被编辑文件位于专属 **worktree** 否则拦截 `Edit`/`Write`/`NotebookEdit`——在共享 checkout 上开 feature 分支**也不行**(仍会被切走),且按**被编辑文件所属的仓库**判断(sibling 仓 `framework`/`cloud` 一并守住)(确属非任务的临时改动用 `OS_ALLOW_MAIN_EDITS=1` 放行)。即便在自己的 worktree 里,下面这些防御性条款仍然适用。
- **绝不 `git stash` —— stash 栈不在上一条的 worktree 隔离范围内。** `git stash` 把栈存在**共享 `.git` 目录**里的 `refs/stash`,**每个 worktree 共用同一个 LIFO 栈**:上一条的物理隔离**不覆盖它**。两个 agent 各自在自己的 worktree 里 stash,push/pop 的是同一个栈 —— 你的 `pop` 取回的是对方刚压进去的改动,你自己的改动留在栈上等着被对方取走;而 `pop` **报成功**,唯一的症状是别人的文件出现在你的 `git status` 里,随后一次 `git add -A` 就把对方的在途工作合进了你的 PR。不是假想:objectui#3430 两个并行 agent 在反向验证中间踩实,双方在途改动都丢了(只能作为 unreachable commit 捞回)。替代做法只有下面这些 —— 都不碰共享状态,都在你自己的 worktree 内,且**首选先 commit 再还原**(上面反向验证那条已把它定为标准写法):

```bash
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,7 +13,7 @@ shared checkout is NOT enough** — it still gets switched under you. You MUST b
**dedicated per-task worktree**:

```
git worktree add ../<repo>-<task> -b <branch> main && cd ../<repo>-<task> && pnpm install
git fetch origin main && git worktree add ../<repo>-<task> -b <branch> origin/main && cd ../<repo>-<task> && pnpm install
```

Make all edits there, **one worktree per repo** a task spans. A PreToolUse hook
Expand Down
Loading