5 Commits

Author SHA1 Message Date
jparkerweb fda0146969 URL updates 2026-08-01 13:04:39 -07:00
jparkerweb 75605e5e41 update URLs 2026-08-01 12:56:52 -07:00
jparkerweb 3b18b42e30 Merge pull request #3 from jparkerweb/statusline-worktree
Add git worktree awareness to status line (v1.16.1)
2026-07-31 22:24:02 -07:00
jparkerweb 8e457fa6e4 Bump to v1.16.1 for status line git worktree awareness 2026-07-31 22:20:38 -07:00
jparkerweb 6740e26261 Add git worktree awareness to status line
Sessions in a linked worktree previously showed only the worktree's
directory name, so the underlying repository was unidentifiable and the
session looked like an unrelated project.

The project segment now renders as "repo | worktree". Repo identity comes
from git rev-parse --git-common-dir, so it is correct regardless of how the
worktree directory was named. A leading repo prefix is stripped from the
worktree name, and the name collapses to a bare marker when it merely
restates the branch already on screen -- matched across / _ . - separators
and type prefixes like feature/, and only when the branch is displayed.

Gated behind the new items.worktree config flag (default on). Costs one
extra timeout-bounded git call, skipped entirely outside git repos.
2026-07-31 22:20:38 -07:00
10 changed files with 143 additions and 34 deletions
+9
View File
@@ -2,6 +2,15 @@
All notable changes to Plan2Code will be documented in this file. All notable changes to Plan2Code will be documented in this file.
## v1.16.1
### ✨ Added
- **Status line: git worktree awareness** — a session running in a linked git worktree now renders the project segment as `repo ⑂ worktree` (e.g. `plan2code ⑂ spike`) instead of only the worktree's directory name, which previously made the session look like an unrelated project
- Repo identity resolved from `git rev-parse --git-common-dir`, so it is correct regardless of how the worktree directory was named (bare `<name>.git` main repos included)
- A leading repo prefix is stripped from the worktree name (`plan2code-user-auth``user-auth`), and the name collapses to a bare `⑂` when it merely restates the branch already on screen — matched across `/ _ . -` separators and type prefixes like `feature/`, and only when the branch is actually displayed
- Toggleable via the new `items.worktree` config flag (default on); one extra timeout-bounded `git` call, skipped outside git repos
## v1.16.0 ## v1.16.0
### ✨ Added ### ✨ Added
+3 -15
View File
@@ -75,14 +75,8 @@ The install script requires **Node.js** (v14 or later). If you don't have Node.j
Run the interactive installer directly using `npx` with your preferred GitHub authentication method: Run the interactive installer directly using `npx` with your preferred GitHub authentication method:
**If you use SSH keys:**
```bash ```bash
npx git+ssh://git@github.com/jparkerweb/plan2code.git npx git+https://code.jparkerweb.com/jparkerweb/plan2code.git
```
**If you use HTTPS authentication:**
```bash
npx git+https://github.com/jparkerweb/plan2code.git
``` ```
This downloads the installer to a temporary location, runs it, installs the workflow files to your machine, and cleans up automatically. The installed workflows remain on your system and work independently. To update or reinstall, simply run the command again. This downloads the installer to a temporary location, runs it, installs the workflow files to your machine, and cleans up automatically. The installed workflows remain on your system and work independently. To update or reinstall, simply run the command again.
@@ -93,14 +87,8 @@ This downloads the installer to a temporary location, runs it, installs the work
Run the interactive installer directly using `npx` with your preferred GitHub authentication method: Run the interactive installer directly using `npx` with your preferred GitHub authentication method:
**If you use SSH keys:**
```bash ```bash
npx git+ssh://git@github.com/jparkerweb/plan2code.git npx git+https://code.jparkerweb.com/jparkerweb/plan2code.git
```
**If you use HTTPS authentication:**
```bash
npx git+https://github.com/jparkerweb/plan2code.git
``` ```
This downloads the installer to a temporary location, runs it, installs the workflow files to your machine, and cleans up automatically. The installed workflows remain on your system and work independently. To update or reinstall, simply run the command again. This downloads the installer to a temporary location, runs it, installs the workflow files to your machine, and cleans up automatically. The installed workflows remain on your system and work independently. To update or reinstall, simply run the command again.
@@ -109,7 +97,7 @@ This downloads the installer to a temporary location, runs it, installs the work
```bash ```bash
# Clone the repository # Clone the repository
git clone https://github.com/jparkerweb/plan2code.git git clone https://code.jparkerweb.com/jparkerweb/plan2code.git
cd plan2code cd plan2code
# Run the interactive installer # Run the interactive installer
+6 -6
View File
@@ -905,7 +905,7 @@
<h1 class="code">CODE</h1> <h1 class="code">CODE</h1>
</div> </div>
<p class="hero-subtitle">The AI workflow that puts planning first</p> <p class="hero-subtitle">The AI workflow that puts planning first</p>
<a href="https://github.com/jparkerweb/plan2code" class="github-link" target="_blank" rel="noopener noreferrer"> <a href="https://code.jparkerweb.com/jparkerweb/plan2code" class="github-link" target="_blank" rel="noopener noreferrer">
<svg class="github-icon" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg> <svg class="github-icon" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
Get the Code Get the Code
</a> </a>
@@ -1083,14 +1083,14 @@
<h3 class="subheadline">Install the workflow</h3> <h3 class="subheadline">Install the workflow</h3>
<p>Run the install script to copy the Plan2Code prompts to your AI assistant workflow directories. Works with Claude Code, Cursor, GitHub Copilot, Windsurf, and more.</p> <p>Run the install script to copy the Plan2Code prompts to your AI assistant workflow directories. Works with Claude Code, Cursor, GitHub Copilot, Windsurf, and more.</p>
<pre class="code-block"><span class="comment"># Clone the repository</span> <pre class="code-block"><span class="comment"># Clone the repository</span>
<span class="command">git clone https://github.com/jparkerweb/plan2code.git</span> <span class="command">git clone https://code.jparkerweb.com/jparkerweb/plan2code.git</span>
<span class="comment"># Navigate to the directory</span> <span class="comment"># Navigate to the directory</span>
<span class="command">cd plan2code</span> <span class="command">cd plan2code</span>
<span class="comment"># Run the interactive installer</span> <span class="comment"># Run the interactive installer</span>
<span class="command">node install.js</span></pre> <span class="command">node install.js</span></pre>
<p><a href="https://github.com/jparkerweb/plan2code" class="inline-link" target="_blank" rel="noopener noreferrer">Get the Code &rarr;</a></p> <p><a href="https://code.jparkerweb.com/jparkerweb/plan2code" class="inline-link" target="_blank" rel="noopener noreferrer">Get the Code &rarr;</a></p>
<div class="install-screenshot"> <div class="install-screenshot">
<img src="install-script.jpg" alt="Plan2Code global installation terminal interface showing platform selection menu"> <img src="install-script.jpg" alt="Plan2Code global installation terminal interface showing platform selection menu">
</div> </div>
@@ -1124,8 +1124,8 @@
<!-- CTA Section --> <!-- CTA Section -->
<section class="cta"> <section class="cta">
<h2 class="cta-text headline"><a class="-plain" href="https://github.com/jparkerweb/plan2code">START<br>PLANNING<br>NOW</a></h2> <h2 class="cta-text headline"><a class="-plain" href="https://code.jparkerweb.com/jparkerweb/plan2code">START<br>PLANNING<br>NOW</a></h2>
<a href="https://github.com/jparkerweb/plan2code" class="cta-button" target="_blank" rel="noopener noreferrer">GET THE CODE</a> <a href="https://code.jparkerweb.com/jparkerweb/plan2code" class="cta-button" target="_blank" rel="noopener noreferrer">GET THE CODE</a>
<p class="cta-subtext">Transform your AI development workflow today</p> <p class="cta-subtext">Transform your AI development workflow today</p>
</section> </section>
@@ -1199,7 +1199,7 @@
document.querySelector('.cta-text').setAttribute('tabindex', '0'); document.querySelector('.cta-text').setAttribute('tabindex', '0');
document.querySelector('.cta-text').addEventListener('keypress', (e) => { document.querySelector('.cta-text').addEventListener('keypress', (e) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
window.open('https://github.com/jparkerweb/plan2code', '_blank'); window.open('https://code.jparkerweb.com/jparkerweb/plan2code', '_blank');
} }
}); });
}); });
+2 -2
View File
@@ -646,7 +646,7 @@ function displayHeader() {
console.log('║ ╰───╯ Welcome to Plan2Code! ║'); console.log('║ ╰───╯ Welcome to Plan2Code! ║');
console.log('║ ║'); console.log('║ ║');
console.log('║ G L O B A L I N S T A L L A T I O N S Y S T E M ║'); console.log('║ G L O B A L I N S T A L L A T I O N S Y S T E M ║');
console.log('║ https://jparkerweb.github.io/plan2code ║'); console.log('║ https://code.jparkerweb.com/jparkerweb/plan2code ║');
console.log('║ ║'); console.log('║ ║');
console.log('╚═════════════════════════════════════════════════════════╝'); console.log('╚═════════════════════════════════════════════════════════╝');
console.log(COLORS.RESET); console.log(COLORS.RESET);
@@ -1299,7 +1299,7 @@ async function install(targets = null) {
if (totalErrors === 0) { if (totalErrors === 0) {
console.log(`${COLORS.GREEN} ╭───╮${COLORS.RESET} ${COLORS.BRIGHT}All done! Happy coding!${COLORS.RESET}`); console.log(`${COLORS.GREEN} ╭───╮${COLORS.RESET} ${COLORS.BRIGHT}All done! Happy coding!${COLORS.RESET}`);
console.log(`${COLORS.GREEN}${COLORS.CYAN}${COLORS.GREEN}${COLORS.RESET} ${COLORS.BRIGHT}If this is your first time using Plan2Code, read the docs here:${COLORS.RESET}`); console.log(`${COLORS.GREEN}${COLORS.CYAN}${COLORS.GREEN}${COLORS.RESET} ${COLORS.BRIGHT}If this is your first time using Plan2Code, read the docs here:${COLORS.RESET}`);
console.log(`${COLORS.GREEN}${COLORS.BRIGHT}${COLORS.GREEN}${COLORS.RESET} ${COLORS.BRIGHT}https://github.com/jparkerweb/plan2code${COLORS.RESET}`); console.log(`${COLORS.GREEN}${COLORS.BRIGHT}${COLORS.GREEN}${COLORS.RESET} ${COLORS.BRIGHT}https://code.jparkerweb.com/jparkerweb/plan2code${COLORS.RESET}`);
console.log(`${COLORS.GREEN} ╰───╯${COLORS.RESET}`); console.log(`${COLORS.GREEN} ╰───╯${COLORS.RESET}`);
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "plan2code", "name": "plan2code",
"version": "1.16.0", "version": "1.16.1",
"private": true, "private": true,
"bin": { "bin": {
"plan2code": "./install.js" "plan2code": "./install.js"
+1 -1
View File
@@ -48,7 +48,7 @@ Examples:
plan2code-bot --resume plan2code-bot --resume
Documentation: Documentation:
https://jparkerweb.github.io/plan2code https://code.jparkerweb.com/jparkerweb/plan2code
`); `);
} }
+31
View File
@@ -20,6 +20,14 @@ A persistent three-line status bar for Claude Code that displays model info, pro
╰─╯ 2m ($0.18) │ ▰▰▱▱▱▱▱▱▱▱▱▱ 18% (36k) │ 88k in · 3k out ╰─╯ 2m ($0.18) │ ▰▰▱▱▱▱▱▱▱▱▱▱ 18% (36k) │ 88k in · 3k out
``` ```
**Git worktree** — session running in a linked worktree at `C:\git\plan2code-user-auth`:
```
╭─╮ Opus 4.6 | High │ plan2code ⑂ │ feature/user-auth │ +12 -3
│★│ ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
╰─╯ 3h 5m ($4.62) │ ▰▰▰▰▰▱▱▱▱▱▱▱ 42% (84k) │ 5h: 28% · 7d: 61%
```
**Line 1:** Planny icon | Model name + reasoning effort | Project name | Git branch | Uncommitted changes **Line 1:** Planny icon | Model name + reasoning effort | Project name | Git branch | Uncommitted changes
**Line 2:** Planny icon | Gray separator **Line 2:** Planny icon | Gray separator
**Line 3:** Planny icon | Session duration + cost | Context window bar | Usage (rate limits or token counts) **Line 3:** Planny icon | Session duration + cost | Context window bar | Usage (rate limits or token counts)
@@ -65,6 +73,7 @@ Edit `~/.claude/statusline-config.json`:
"model": true, "model": true,
"effort": true, "effort": true,
"project": true, "project": true,
"worktree": true,
"branch": true, "branch": true,
"contextBar": true, "contextBar": true,
"planUsage": true, "planUsage": true,
@@ -83,6 +92,7 @@ Edit `~/.claude/statusline-config.json`:
| `items.model` | `true` | Show model name (Opus, Sonnet, Haiku) | | `items.model` | `true` | Show model name (Opus, Sonnet, Haiku) |
| `items.effort` | `true` | Append the current reasoning effort level (Low/Medium/High/XHigh/Max) to the model segment, e.g. `Sonnet 5 \| High`. Reads `effort.level` from stdin; hidden when the current model doesn't support an effort parameter (field absent from stdin). | | `items.effort` | `true` | Append the current reasoning effort level (Low/Medium/High/XHigh/Max) to the model segment, e.g. `Sonnet 5 \| High`. Reads `effort.level` from stdin; hidden when the current model doesn't support an effort parameter (field absent from stdin). |
| `items.project` | `true` | Show project directory name | | `items.project` | `true` | Show project directory name |
| `items.worktree` | `true` | Detect [git worktrees](https://git-scm.com/docs/git-worktree) and render the project segment as `repo ⑂ worktree` instead of just the worktree's directory name. See [Worktree Display](#worktree-display). Requires `items.project`. |
| `items.branch` | `true` | Show current git branch (falls back to short SHA when detached HEAD) | | `items.branch` | `true` | Show current git branch (falls back to short SHA when detached HEAD) |
| `items.contextBar` | `true` | Show context window usage bar with percentage | | `items.contextBar` | `true` | Show context window usage bar with percentage |
| `items.contextTokens` | `true` | Append raw tokens used in the context window next to the percentage, e.g. `42% (84k)`. Reads `context_window.total_input_tokens` (the same input-token count `used_percentage` is derived from — excludes output tokens). Requires `items.contextBar` to also be enabled. | | `items.contextTokens` | `true` | Append raw tokens used in the context window next to the percentage, e.g. `42% (84k)`. Reads `context_window.total_input_tokens` (the same input-token count `used_percentage` is derived from — excludes output tokens). Requires `items.contextBar` to also be enabled. |
@@ -101,6 +111,27 @@ Malformed config falls back to defaults silently. Type errors on individual keys
| Copilot CLI | Planned | Deferred — CLI lacks status line script support as of v0.0.421 | | Copilot CLI | Planned | Deferred — CLI lacks status line script support as of v0.0.421 |
| Others | Not supported | Codex CLI, Gemini CLI have built-in status, not scriptable | | Others | Not supported | Codex CLI, Gemini CLI have built-in status, not scriptable |
## Worktree Display
With `items.worktree` disabled, a session in a linked worktree shows only that worktree's directory name (`plan2code-user-auth`) — the underlying repository identity is lost, and the session looks like an unrelated project.
When enabled, the project segment becomes `repo ⑂ worktree`:
| Worktree directory | Branch | Rendered | Why |
|--------------------|--------|----------|-----|
| `plan2code` (primary checkout) | `main` | `plan2code` | Not a linked worktree — unchanged |
| `plan2code-spike` | `spike-thing` | `plan2code ⑂ spike` | Repo prefix stripped from the worktree name |
| `plan2code-user-auth` | `feature/user-auth` | `plan2code ⑂` | Name is redundant with the visible branch — collapses to the bare marker |
| `plan2code-user-auth` | `feature/user-auth`, `items.branch: false` | `plan2code ⑂ user-auth` | No branch shown, so the name is kept |
Details:
- **Detection** — a single `git rev-parse --git-dir --git-common-dir`. The two paths differ only inside a linked worktree. The true repo name comes from `--git-common-dir` (its parent directory, or the `<name>.git` basename for a bare main repo), so it is correct regardless of how the worktree directory was named.
- **Prefix stripping** — a leading repo name followed by `-`, `_`, or `.` is removed, so `plan2code-user-auth` reads as `user-auth`.
- **Redundancy collapse** — worktree directories usually mirror their branch. The name is dropped (leaving `⑂`) when it matches the branch after normalizing case and `/ _ . -` separators, compared against both the full branch and its trailing segment so type prefixes like `feature/` don't defeat the match. This only applies when the branch is actually displayed.
- **Color** — the repo keeps its bold silver; the `⑂` marker and worktree name render in amber so a non-primary checkout is obvious at a glance. Monochrome output is `repo ⑂ worktree`.
- **Cost** — one extra `git` invocation, subject to the same 1.5s timeout, and skipped entirely outside git repos.
## Usage Display ## Usage Display
The usage segment reads data directly from Claude Code's stdin JSON — no API calls, no auth needed, no background processes. The usage segment reads data directly from Claude Code's stdin JSON — no API calls, no auth needed, no background processes.
@@ -6,6 +6,7 @@
"model": true, "model": true,
"effort": true, "effort": true,
"project": true, "project": true,
"worktree": true,
"branch": true, "branch": true,
"contextBar": true, "contextBar": true,
"contextTokens": true, "contextTokens": true,
+85 -5
View File
@@ -28,6 +28,7 @@ const DEFAULTS = {
model: true, model: true,
effort: true, effort: true,
project: true, project: true,
worktree: true,
branch: true, branch: true,
contextBar: true, contextBar: true,
contextTokens: true, contextTokens: true,
@@ -90,6 +91,7 @@ const C = {
// Plan2Code brand // Plan2Code brand
teal: rgb(190, 192, 200), // Silver — repo teal: rgb(190, 192, 200), // Silver — repo
sky: rgb(120, 195, 255), // Light sky blue — branch sky: rgb(120, 195, 255), // Light sky blue — branch
amber: rgb(235, 170, 95), // Amber — linked worktree marker
muted: rgb(40, 120, 200), // Mid blue — model muted: rgb(40, 120, 200), // Mid blue — model
label: rgb(130, 135, 150), // Mid gray — field labels (5h, 7d) label: rgb(130, 135, 150), // Mid gray — field labels (5h, 7d)
// Bar & quota thresholds // Bar & quota thresholds
@@ -150,6 +152,54 @@ function getGitBranch(stdinData) {
return sha || ''; return sha || '';
} }
// Linked worktrees have their own .git dir under the main repo's
// .git/worktrees/<name>, while --git-common-dir still points at the main repo's
// .git. Equal paths mean we're in the primary checkout.
function getWorktreeInfo(cwd) {
const raw = gitExec(['rev-parse', '--git-dir', '--git-common-dir'], cwd);
if (!raw) return null;
const [gitDir, commonDir] = raw.split('\n').map((p) => path.resolve(cwd, p.trim()));
if (!gitDir || !commonDir) return null;
const samePath = process.platform === 'win32'
? gitDir.toLowerCase() === commonDir.toLowerCase()
: gitDir === commonDir;
if (samePath) return null;
// commonDir is normally <repo>/.git; bare repos use <name>.git directly
const commonBase = path.basename(commonDir);
const repoName = commonBase === '.git'
? path.basename(path.dirname(commonDir))
: commonBase.replace(/\.git$/i, '');
const toplevel = gitExec(['rev-parse', '--show-toplevel'], cwd);
const worktreeName = path.basename(toplevel || cwd);
if (!repoName || !worktreeName) return null;
return { repoName, worktreeName };
}
// "plan2code-user-auth" in repo "plan2code" reads as just "user-auth"
function stripRepoPrefix(worktreeName, repoName) {
const lowerWt = worktreeName.toLowerCase();
const lowerRepo = repoName.toLowerCase();
if (!lowerWt.startsWith(lowerRepo) || lowerWt === lowerRepo) return worktreeName;
const rest = worktreeName.slice(repoName.length);
return /^[-_.]/.test(rest) ? rest.slice(1) : worktreeName;
}
const normalizeName = (s) => s.toLowerCase().replace(/[/_.\s-]+/g, '-').replace(/^-|-$/g, '');
// Worktree dirs usually mirror their branch (plan2code-user-auth / feature/user-auth).
// Compare against both the full branch and its trailing segment so the common
// type prefixes (feature/, bugfix/, ...) don't defeat the match.
function isRedundantWithBranch(worktreeName, branch) {
if (!branch) return false;
const candidates = new Set([normalizeName(branch), normalizeName(branch.split('/').pop())]);
return candidates.has(normalizeName(worktreeName));
}
// ============================================================================ // ============================================================================
// Formatters // Formatters
// ============================================================================ // ============================================================================
@@ -192,6 +242,34 @@ function getProjectName(stdinData) {
return path.basename(projectDir); return path.basename(projectDir);
} }
// Returns the project segment: "plan2code" normally, "plan2code ⑂ spike" in a
// linked worktree — the name collapsing to a bare ⑂ when the branch says it already.
function formatProject(stdinData, config, branch) {
const project = getProjectName(stdinData);
if (!project) return null;
const plain = (text) => (config.color ? `${C.bold}${C.teal}${text}${C.reset}` : text);
if (!config.items.worktree) return plain(project);
const cwd = stdinData?.workspace?.project_dir || process.cwd();
if (!isGitRepo(cwd)) return plain(project);
const info = getWorktreeInfo(cwd);
if (!info) return plain(project);
const shortName = stripRepoPrefix(info.worktreeName, info.repoName);
// Only dedupe against a branch the user can actually see — otherwise the
// worktree identity would vanish entirely.
const visibleBranch = config.items.branch ? branch : '';
const redundant = isRedundantWithBranch(shortName, visibleBranch)
|| isRedundantWithBranch(info.worktreeName, visibleBranch)
|| normalizeName(shortName) === normalizeName(info.repoName);
const marker = redundant ? '⑂' : `${shortName}`;
if (!config.color) return `${info.repoName} ${marker}`;
return `${C.bold}${C.teal}${info.repoName}${C.reset} ${C.amber}${marker}${C.reset}`;
}
function calculateContextPercent(stdinData, config) { function calculateContextPercent(stdinData, config) {
const cw = stdinData?.context_window; const cw = stdinData?.context_window;
if (!cw) return null; if (!cw) return null;
@@ -339,14 +417,16 @@ function formatLine1(stdinData, config) {
} }
} }
// Branch is resolved first — the project segment dedupes the worktree name against it
const branch = config.items.branch || config.items.worktree ? getGitBranch(stdinData) : '';
if (config.items.project) { if (config.items.project) {
const project = getProjectName(stdinData); const project = formatProject(stdinData, config, branch);
if (project) segments.push(config.color ? `${C.bold}${C.teal}${project}${C.reset}` : project); if (project) segments.push(project);
} }
if (config.items.branch) { if (config.items.branch && branch) {
const branch = getGitBranch(stdinData); segments.push(config.color ? `${C.sky}${branch}${C.reset}` : branch);
if (branch) segments.push(config.color ? `${C.sky}${branch}${C.reset}` : branch);
} }
if (config.items.linesChanged) { if (config.items.linesChanged) {
+4 -4
View File
@@ -1,6 +1,6 @@
{ {
"name": "Plan2Code", "name": "Plan2Code",
"version": "1.16.0", "version": "1.16.1",
"description": "A structured 4-step workflow methodology for AI-assisted software development", "description": "A structured 4-step workflow methodology for AI-assisted software development",
"keywords": [ "keywords": [
"ai", "ai",
@@ -14,10 +14,10 @@
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/jparkerweb/plan2code" "url": "https://code.jparkerweb.com/jparkerweb/plan2code"
}, },
"homepage": "https://plan2code.jparkerweb.com", "homepage": "https://code.jparkerweb.com/jparkerweb/plan2code",
"releaseDate": "2026-07-20", "releaseDate": "2026-07-31",
"mode": "utility" "mode": "utility"
} }