You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This fork runs a two-root split: ~/.claude/ = CC config, ~/.pai/ = PAI code. Upstream (danielmiessler/PAI) runs single-root: everything under ~/.claude/.
This asymmetry creates friction every time we absorb an upstream release or cherry. References to ~/.claude/<thing> in upstream-shaped source have to be translated per-occurrence to ~/.pai/<thing> in our layout — in hooks, skills, agents, docs, installer templates, and release-tree mirrors.
The split is an invariant we impose. Upstream doesn't know about it. Each upstream release carries references written in upstream's single-root worldview, and we pay translation cost proportional to release size — not because the semantics changed, but because the path strings disagree.
We want upstream absorption to be predominantly mechanical: apply the diff, let one boundary layer handle the translation, done. Not a bespoke per-file audit every time.
Possible directions (for investigation, non-exhaustive)
Canonical shape in repo = upstream's. Keep repo paths upstream-shaped under .claude/.... Installer translates to two-root at install time. Cherries apply as-is. Cost: any doc/comment text that doesn't go through the installer keeps the upstream worldview indefinitely, or we accept a post-install doc-rewrite pass.
Path-indirection layer. Replace literal path strings in source with an abstraction that resolves identically on both upstream and fork. Requires a naming convention, or a rewrite step at sync time.
Inverted canonical layout with sync-time rewriter. Keep .pai/... shape as source-of-truth in repo; translate upstream paths at sync time via scripted rewriter. Sync becomes automated rather than manual review. Cost: tooling to maintain and verify; round-trip cherries (upstream → us → upstream) become harder.
Context
This fork runs a two-root split:
~/.claude/= CC config,~/.pai/= PAI code. Upstream (danielmiessler/PAI) runs single-root: everything under~/.claude/.This asymmetry creates friction every time we absorb an upstream release or cherry. References to
~/.claude/<thing>in upstream-shaped source have to be translated per-occurrence to~/.pai/<thing>in our layout — in hooks, skills, agents, docs, installer templates, and release-tree mirrors.Recent evidence:
~/.claude/...literals missed during the initial split migration.Problem
The split is an invariant we impose. Upstream doesn't know about it. Each upstream release carries references written in upstream's single-root worldview, and we pay translation cost proportional to release size — not because the semantics changed, but because the path strings disagree.
We want upstream absorption to be predominantly mechanical: apply the diff, let one boundary layer handle the translation, done. Not a bespoke per-file audit every time.
Possible directions (for investigation, non-exhaustive)
Canonical shape in repo = upstream's. Keep repo paths upstream-shaped under
.claude/.... Installer translates to two-root at install time. Cherries apply as-is. Cost: any doc/comment text that doesn't go through the installer keeps the upstream worldview indefinitely, or we accept a post-install doc-rewrite pass.Path-indirection layer. Replace literal path strings in source with an abstraction that resolves identically on both upstream and fork. Requires a naming convention, or a rewrite step at sync time.
Inverted canonical layout with sync-time rewriter. Keep
.pai/...shape as source-of-truth in repo; translate upstream paths at sync time via scripted rewriter. Sync becomes automated rather than manual review. Cost: tooling to maintain and verify; round-trip cherries (upstream → us → upstream) become harder.Plugin distribution (Investigate distributing PAI as a Claude Code plugin #102). Sidesteps the whole thing by exiting the
~/.claude/namespace entirely. Long-term answer, scoped separately.Hybrid / other framings the investigation surfaces.
Success criteria
PAI_DIR=~/.pai, CC config at~/.claude/) are preserved at runtime.Out of scope
Prior art