claude-dev-env 2.5.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +20 -57
- package/_shared/pr-loop/scripts/code_rules_gate.py +2 -1
- package/_shared/pr-loop/scripts/code_rules_gate_parts/CLAUDE.md +12 -2
- package/_shared/pr-loop/scripts/code_rules_gate_parts/baseline_import_isolation.py +309 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_regression.py +540 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_running.py +206 -70
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/__init__.py +1 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/_repo_test_helpers.py +76 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_baseline_import_isolation.py +248 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_regression.py +309 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_running.py +91 -58
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +202 -0
- package/agents/CLAUDE.md +1 -1
- package/agents/code-verifier.md +36 -7
- package/bin/codex-compat.mjs +104 -0
- package/bin/codex-compat.test.mjs +51 -0
- package/codex-capability-map.json +13 -0
- package/docs/CODE_RULES.md +2 -0
- package/docs/codex-compatibility.md +25 -0
- package/docs/nas-ssh-invocation.md +96 -12
- package/docs/references/code-review-enforcement.md +31 -6
- package/hooks/blocking/CLAUDE.md +3 -0
- package/hooks/blocking/config/code_review_enforcement_constants.py +40 -10
- package/hooks/blocking/config/test_code_review_enforcement_constants.py +56 -3
- package/hooks/blocking/eli11_reply_enforcer.py +479 -0
- package/hooks/blocking/gh_body_arg_blocker.py +1 -1
- package/hooks/blocking/nas_ssh_binary_enforcer.py +8 -46
- package/hooks/blocking/shell_substitution_blocker.py +129 -0
- package/hooks/blocking/state_description_blocker.py +1 -1
- package/hooks/blocking/stop_dispatcher.py +1 -1
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +2 -3
- package/hooks/blocking/test_eli11_reply_enforcer.py +457 -0
- package/hooks/blocking/test_shell_substitution_blocker.py +124 -0
- package/hooks/blocking/test_stop_dispatcher.py +23 -0
- package/hooks/blocking/test_unscoped_search_blocker.py +102 -0
- package/hooks/blocking/test_verdict_directory_write_blocker.py +4 -8
- package/hooks/blocking/unscoped_search_blocker.py +391 -0
- package/hooks/git-hooks/CLAUDE.md +3 -0
- package/hooks/git-hooks/conftest.py +30 -0
- package/hooks/git-hooks/gate_utils.py +2 -2
- package/hooks/git-hooks/git_hooks_constants/__init__.py +41 -2
- package/hooks/git-hooks/pre_push.py +75 -4
- package/hooks/git-hooks/pre_push_base_reference.py +166 -0
- package/hooks/git-hooks/test_config.py +0 -15
- package/hooks/git-hooks/test_gate_utils.py +3 -15
- package/hooks/git-hooks/test_pre_commit.py +1 -15
- package/hooks/git-hooks/test_pre_push.py +236 -27
- package/hooks/git-hooks/test_pre_push_base_reference.py +339 -0
- package/hooks/hooks.json +0 -12
- package/hooks/hooks_constants/CLAUDE.md +5 -1
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +4 -4
- package/hooks/hooks_constants/eli11_reply_enforcer_constants.py +101 -0
- package/hooks/hooks_constants/nas_ssh_binary_enforcer_constants.py +2 -8
- package/hooks/hooks_constants/shell_command_segments.py +82 -0
- package/hooks/hooks_constants/shell_substitution_blocker_constants.py +67 -0
- package/hooks/hooks_constants/stop_dispatcher_constants.py +1 -0
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +5 -6
- package/hooks/hooks_constants/test_stop_dispatcher_constants.py +1 -0
- package/hooks/hooks_constants/unscoped_search_blocker_constants.py +153 -0
- package/package.json +4 -2
- package/rules/CLAUDE.md +17 -23
- package/rules/agent-spawn-protocol.md +6 -6
- package/rules/anti-corollary-tests.md +1 -1
- package/rules/bdd.md +1 -1
- package/rules/cleanup-temp-files.md +10 -4
- package/rules/code-standards.md +7 -0
- package/rules/conservative-action.md +1 -5
- package/rules/context7.md +0 -4
- package/rules/destructive-commands.md +47 -0
- package/rules/doc-inventory-integrity.md +48 -0
- package/rules/doc-prose-cuts.md +58 -0
- package/rules/docstring-prose-matches-implementation.md +10 -2
- package/rules/durable-post-artifacts.md +0 -4
- package/rules/eli11-replies.md +31 -0
- package/rules/explore-thoroughly.md +4 -4
- package/rules/falsify-before-green.md +68 -0
- package/rules/file-global-constants.md +1 -1
- package/rules/filesystem-search.md +51 -0
- package/rules/gh-cli-conventions.md +27 -0
- package/rules/git-workflow.md +26 -0
- package/rules/hedging-claims.md +9 -0
- package/rules/long-horizon-autonomy.md +0 -4
- package/rules/measurement-denominators.md +48 -0
- package/rules/nas-ssh-invocation.md +23 -5
- package/rules/parallel-tools.md +2 -2
- package/rules/plain-illustrative-docstrings.md +3 -7
- package/rules/plain-language.md +2 -0
- package/rules/proof-of-work-pr-comments.md +0 -4
- package/rules/re-stage-before-commit.md +2 -0
- package/rules/research-mode.md +10 -0
- package/rules/shell-invocation.md +21 -0
- package/rules/testing.md +4 -0
- package/rules/verified-commit-gate-skip.md +3 -27
- package/rules/verify-before-asking.md +5 -0
- package/rules/windows-filesystem-safe.md +1 -1
- package/rules/workers-done-before-complete.md +4 -0
- package/scripts/Migrate-ShellPolicy.ps1 +1 -1
- package/scripts/codex_capability_bridge.py +171 -0
- package/scripts/codex_compat_materializer.py +1087 -0
- package/scripts/codex_compat_watcher.py +502 -0
- package/scripts/dev_env_scripts_constants/code_review_constants.py +37 -0
- package/scripts/invoke_code_review.py +11 -4
- package/scripts/sync_to_cursor/rules.py +0 -10
- package/scripts/test_invoke_code_review.py +143 -0
- package/scripts/test_invoke_code_review_chain.py +1 -1
- package/scripts/test_invoke_code_review_contract.py +1 -1
- package/scripts/tests/test_code_review_constants.py +80 -0
- package/scripts/tests/test_codex_capability_bridge.py +91 -0
- package/scripts/tests/test_codex_compat_materializer.py +632 -0
- package/scripts/tests/test_codex_compat_watcher.py +599 -0
- package/scripts/tests/test_sync_to_cursor.py +0 -1
- package/skills/autoconverge/workflow/converge.mjs +1 -1
- package/skills/bugteam/reference/copilot-gap-analysis.md +1 -1
- package/skills/condensing-instructions/SKILL.md +42 -51
- package/skills/fresh-branch/CLAUDE.md +1 -1
- package/skills/fresh-branch/SKILL.md +5 -6
- package/skills/fresh-branch/scripts/create_fresh_branch.py +42 -24
- package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/fresh_branch_cli_constants.py +1 -3
- package/skills/fresh-branch/scripts/test_create_fresh_branch.py +30 -126
- package/skills/orchestrator/SKILL.md +23 -9
- package/skills/orchestrator-refresh/SKILL.md +20 -1
- package/skills/privacy-hygiene/reference/sweep-procedure.md +1 -1
- package/skills/session-log/SKILL.md +1 -1
- package/rules/claude-md-orphan-file.md +0 -28
- package/rules/cleanup-command-forms.md +0 -23
- package/rules/code-reviews.md +0 -11
- package/rules/env-var-table-code-drift.md +0 -10
- package/rules/gh-body-file.md +0 -5
- package/rules/gh-paginate.md +0 -3
- package/rules/hook-prose-matches-detector.md +0 -15
- package/rules/no-historical-clutter.md +0 -26
- package/rules/no-inline-destructive-literals.md +0 -9
- package/rules/no-justification-noise.md +0 -61
- package/rules/package-inventory-stale-entry.md +0 -25
- package/rules/right-sized-engineering.md +0 -28
- package/rules/self-contained-docs.md +0 -17
- package/rules/shell-invocation-policy.md +0 -5
- package/rules/state-what-is.md +0 -25
- package/rules/tdd.md +0 -7
|
@@ -1,81 +1,72 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: condensing-instructions
|
|
3
3
|
description: >-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
Refine an instruction document for Claude 5 generation models: cut rules the
|
|
5
|
+
model's judgment already covers, move detail behind progressive disclosure,
|
|
6
|
+
and route each remaining piece to the system prompt, CLAUDE.md, a skill, or a
|
|
7
|
+
reference. Use for system prompts, CLAUDE.md files, skills, tool
|
|
8
|
+
descriptions, agent instructions, context engineering, prompt slimming, and
|
|
9
|
+
token reduction.
|
|
9
10
|
---
|
|
10
11
|
|
|
11
12
|
# Condensing Instructions
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
Cut an instruction document to what a Claude 5 generation model needs, and move the rest to the surface that loads it on demand. Over 80% of Claude Code's system prompt came out for Claude Opus 5 and Claude Fable 5 with no measurable drop in performance, so treat a long instruction document as a place with room to cut.
|
|
14
15
|
|
|
15
|
-
##
|
|
16
|
+
## Clear the conflicts first
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
Read the system prompt, the CLAUDE.md, and the skills as one body of text and find the lines that pull against each other — "leave documentation as appropriate" sitting beside "DO NOT add comments". A conflict makes the model deliberate at length before it acts. Resolve each pair into one statement, or delete both when neither changes what the model does.
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
## Trade rules for judgment
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
Delete a rule written to block a worst case, such as file deletion. Claude 5 generation models read the surrounding context and decide well without it, and a rigid rule blocks the user who has a real reason to want the behavior it forbids.
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
State the outcome and the signal the model should read:
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
- Cut: "Default to writing no comments. Never write multi-paragraph docstrings or multi-line comment blocks — one short line max. Don't create planning, decision, or analysis documents unless the user asks for them."
|
|
27
|
+
- Keep: "Write code that reads like the surrounding code: match its comment density, naming, and idiom."
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
## Design the interface in place of examples
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
Examples constrain exploration. Carry usage in the tool's own shape: expressive names, expressive parameters, and types that signal intent. A status parameter enumerated as `pending`, `in_progress`, `completed` shows correct use with no example attached.
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
## Load detail at the point of use
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
Move detail out of always-on text and into a surface the model reaches for:
|
|
34
36
|
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
- Within a group, put prerequisites before actions, general rules before narrow exceptions, and production requirements before their checks.
|
|
39
|
-
- Put each exception beside the rule it modifies. State precedence when rules overlap.
|
|
40
|
-
- Give each rule one authoritative location. State a shared actor, condition, default, or scope once at the narrowest level that covers every affected rule.
|
|
41
|
-
- Let a heading carry scope only when every instruction beneath it clearly inherits that scope. Use the fewest headings that preserve navigation.
|
|
37
|
+
- A skill the model calls when the task calls for it. Code review and verification detail belongs here.
|
|
38
|
+
- A linked file the model opens on demand.
|
|
39
|
+
- A tool with deferred loading, where the model searches for the definition before it uses the tool.
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
Keep the always-on context lean and let the model pull the rest.
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
- Preserve force and quantifiers. Keep `must`, `never`, `only`, `should`, `may`, `all`, `any`, and exact counts distinct.
|
|
47
|
-
- Combine statements only when their actor, force, scope, trigger, timing, persistence, and exceptions align.
|
|
48
|
-
- Replace true repetition with one rule and a compact list of affected cases. Keep separate statements when repetition protects distinct stages, scopes, or failure modes.
|
|
49
|
-
- Use one sentence per decision. Join clauses only when they form one testable rule.
|
|
50
|
-
- Use paragraphs for cohesive rules and lists for parallel obligations, mappings, or branches. Avoid decorative headings and structural ceremony.
|
|
51
|
-
- Remove non-operative background, history, rationale, transition text, conversational framing, restatement, setup narration, and examples. Remove inventories or folder maps that merely describe the document.
|
|
52
|
-
- Use one term for each concept. Define unfamiliar terms at first use. Do not compress complete sentences into fragments, stacked jargon, or vague shorthand.
|
|
53
|
-
- Preserve operational literals character for character, including spelling, case, punctuation, quoting, and placeholders. Preserve whether a list is exhaustive or illustrative; never replace an exact enumeration with `etc.` or a broader category.
|
|
43
|
+
## Say each thing once
|
|
54
44
|
|
|
55
|
-
|
|
45
|
+
Put tool usage guidance in the tool description alone. Delete the copy that repeats it in the system prompt.
|
|
56
46
|
|
|
57
|
-
|
|
47
|
+
## Let memory carry session facts
|
|
58
48
|
|
|
59
|
-
|
|
49
|
+
Claude's automatic memory captures relevant context and carries it across sessions. Delete hand-written memory notes from CLAUDE.md when memory already holds them.
|
|
60
50
|
|
|
61
|
-
|
|
51
|
+
## Point at rich references
|
|
62
52
|
|
|
63
|
-
|
|
53
|
+
Include files as references with @mentions. Prefer a reference the model can read with no ambiguity, in this order:
|
|
64
54
|
|
|
65
|
-
|
|
55
|
+
1. Code from this or another codebase — the highest fidelity specification available.
|
|
56
|
+
2. A test suite that pins the behavior.
|
|
57
|
+
3. An HTML artifact or a mockup.
|
|
58
|
+
4. A rubric, which lets a verification agent score work against a quality standard.
|
|
59
|
+
5. Prose description or a screenshot.
|
|
66
60
|
|
|
67
|
-
|
|
68
|
-
2. **Support:** Map every material clause back to a stated or confirmed requirement; remove invented behavior.
|
|
69
|
-
3. **Fidelity:** Compare force, negation, quantifiers, actor, object or type, scope, conditions, exceptions, dependencies, order, timing, persistence, failure behavior, outputs, and protected literals. Nothing may be weakened, broadened, narrowed, contradicted, or altered character for character where exactness matters.
|
|
70
|
-
4. **Boundary behavior:** Test the normal case, each branch and exception, prohibited cases, missing dependencies, failures, and acceptance checks when present. Each case must yield the intended action.
|
|
71
|
-
5. **Clarity:** Resolve ambiguous references, hidden precedence, scattered exceptions, inconsistent terms, and unclear qualifier scope.
|
|
72
|
-
6. **Density:** Delete any sentence that changes no behavior, safety boundary, interpretation, or validation result. Merge remaining text only when the boundary stays equally clear.
|
|
73
|
-
7. **Independent use:** Reconstruct the ledger from only the finished document. It must stand alone without background or unstated context.
|
|
61
|
+
## Route what remains
|
|
74
62
|
|
|
75
|
-
|
|
63
|
+
| Surface | What belongs there |
|
|
64
|
+
|---|---|
|
|
65
|
+
| System prompt | The product Claude works within and the role it plays. For a custom agent, spend real effort here. |
|
|
66
|
+
| CLAUDE.md | A short line on what the repository is, then the gotchas found inside the codebase. Drop anything the model can read off the file structure. Link to skills for the detail. |
|
|
67
|
+
| Skills | Opinions, knowledge, and practices particular to your team or product, written as a guide the model consults. Split a long skill into several files. Constrain only where it matters. |
|
|
68
|
+
| References | Specs, mockups, and codebases pulled in by @mention. |
|
|
76
69
|
|
|
77
|
-
## Deliver
|
|
70
|
+
## Deliver
|
|
78
71
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
For text supplied in the conversation, output only the finished instruction document. For file tasks, write only the requested paths: edit an existing file in place, and create a new file only when requested. Report changed paths with a concise behavior summary. Do not include the ledger or process narration unless requested.
|
|
72
|
+
Rewrite the document in place and report what moved to which surface. Offer `claude doctor` as a follow-up pass — it rightsizes skills and CLAUDE.md files against these same rules.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# fresh-branch
|
|
2
2
|
|
|
3
|
-
Creates a new branch from fresh-fetched `origin/main` inside an isolated worktree under
|
|
3
|
+
Creates a new branch from fresh-fetched `origin/main` inside an isolated worktree under `<repo-root>/.claude/worktrees/<agent>/<branch-name>`. Does not push, open a PR, or run `checkout -b` in the caller tree.
|
|
4
4
|
|
|
5
5
|
## Key files
|
|
6
6
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: fresh-branch
|
|
3
3
|
description: >-
|
|
4
|
-
Fresh git branch from origin/main in an isolated
|
|
4
|
+
Fresh git branch from origin/main in an isolated worktree under the repo's .claude/worktrees/ (never checkout -b in the caller tree).
|
|
5
5
|
Triggers: fresh branch, new branch from main, /fresh-branch, start fresh, clean branch off main,
|
|
6
6
|
worktree branch, branch in temp.
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# fresh-branch
|
|
10
10
|
|
|
11
|
-
Creates a new branch from a fresh-fetched `origin/main` inside an isolated git worktree under the agent
|
|
11
|
+
Creates a new branch from a fresh-fetched `origin/main` inside an isolated git worktree under the repository's `.claude/worktrees/<agent>/` root. Shared primitive: other skills invoke `/fresh-branch` when they need a clean branch without touching the caller's dirty tree.
|
|
12
12
|
|
|
13
13
|
**Announce at start:** "Creating a fresh branch from origin/main."
|
|
14
14
|
|
|
@@ -62,15 +62,14 @@ Optional flags:
|
|
|
62
62
|
| Flag | Role |
|
|
63
63
|
|------|------|
|
|
64
64
|
| `--repo <path>` | Source repo (default: current directory) |
|
|
65
|
-
| `--agent <slug>` |
|
|
65
|
+
| `--agent <slug>` | Worktree-root segment: `claude`, `grok`, `cursor`, `codex`, … |
|
|
66
66
|
| `--base <ref>` | Base ref (default: `origin/main`) |
|
|
67
67
|
|
|
68
68
|
Agent resolution inside the script: `--agent` → `FRESH_BRANCH_AGENT` env → host markers → `claude`.
|
|
69
69
|
|
|
70
70
|
Worktree path:
|
|
71
71
|
|
|
72
|
-
-
|
|
73
|
-
- Else: `${tmpdir}/<agent>/<branch-name>`
|
|
72
|
+
- `<repo-root>/.claude/worktrees/<agent>/<branch-name>`, on every platform
|
|
74
73
|
- If the path exists, the script suffixes `-2`, `-3`, …
|
|
75
74
|
|
|
76
75
|
On exit 0, stdout is one JSON object:
|
|
@@ -101,7 +100,7 @@ Further edits for the new branch belong in `worktree_path`, not in the caller's
|
|
|
101
100
|
|
|
102
101
|
## Gotchas
|
|
103
102
|
|
|
104
|
-
- **Dirty caller cwd blocks `checkout -b` and pollutes the tree.** Phase 3 always uses `git worktree add -b` into
|
|
103
|
+
- **Dirty caller cwd blocks `checkout -b` and pollutes the tree.** Phase 3 always uses `git worktree add -b` into `<repo-root>/.claude/worktrees/<agent>/…`. If you reconstruct Phase 3 by hand with `checkout -b` in the session cwd, local modifications block the checkout and leave the user on a half-switched branch.
|
|
105
104
|
- **Caller HEAD must stay put.** After success, the original repo's checked-out branch and dirty files are unchanged; only the new worktree has the new branch.
|
|
106
105
|
- **Branch name collision.** If the branch already exists, the script exits non-zero with `{"error":...}`. Pick a new name; do not delete remote branches unless the user asks.
|
|
107
106
|
- **Path already occupied.** A leftover folder at the preferred worktree path gets a numeric suffix (`-2`, …); report the path from JSON, not the path you assumed.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""Create a fresh branch in an isolated git worktree under the
|
|
2
|
+
"""Create a fresh branch in an isolated git worktree under the repository.
|
|
3
3
|
|
|
4
4
|
::
|
|
5
5
|
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
"base_commit": "abc...", "agent": "claude", "repo_root": "..."}
|
|
9
9
|
|
|
10
10
|
Never runs ``git checkout -b`` in the caller's working tree. Fetches the base
|
|
11
|
-
ref, then ``git worktree add -b --no-track`` into
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
ref, then ``git worktree add -b --no-track`` into
|
|
12
|
+
``<repo-root>/.claude/worktrees/<agent>/<branch>``. Exit 0 prints success JSON;
|
|
13
|
+
any failure prints ``{"error": ...}`` and exits non-zero.
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
from __future__ import annotations
|
|
@@ -20,7 +20,6 @@ import json
|
|
|
20
20
|
import os
|
|
21
21
|
import re
|
|
22
22
|
import sys
|
|
23
|
-
import tempfile
|
|
24
23
|
from pathlib import Path
|
|
25
24
|
|
|
26
25
|
from fresh_branch_git_commands import (
|
|
@@ -33,7 +32,7 @@ from fresh_branch_git_commands import (
|
|
|
33
32
|
from fresh_branch_scripts_constants.fresh_branch_cli_constants import (
|
|
34
33
|
AGENT_SLUG_PATTERN,
|
|
35
34
|
ALL_AGENT_DETECTION_MARKERS,
|
|
36
|
-
|
|
35
|
+
ALL_REPOSITORY_WORKTREE_ROOT_PARTS,
|
|
37
36
|
DEFAULT_AGENT_SLUG,
|
|
38
37
|
DEFAULT_BASE_REF,
|
|
39
38
|
ERROR_AGENT_SLUG_INVALID,
|
|
@@ -57,8 +56,6 @@ from fresh_branch_scripts_constants.fresh_branch_cli_constants import (
|
|
|
57
56
|
PAYLOAD_KEY_REPO_ROOT,
|
|
58
57
|
PAYLOAD_KEY_WORKTREE_PATH,
|
|
59
58
|
UNIQUE_PATH_SUFFIX_START,
|
|
60
|
-
USERPROFILE_ENV_VAR,
|
|
61
|
-
WINDOWS_PLATFORM_PREFIX,
|
|
62
59
|
)
|
|
63
60
|
|
|
64
61
|
|
|
@@ -94,28 +91,26 @@ def _detect_agent_slug_from_environment() -> str:
|
|
|
94
91
|
return DEFAULT_AGENT_SLUG
|
|
95
92
|
|
|
96
93
|
|
|
97
|
-
def resolve_agent_worktree_root(agent_slug: str) -> Path:
|
|
98
|
-
"""Return
|
|
94
|
+
def resolve_agent_worktree_root(repo_root: Path, agent_slug: str) -> Path:
|
|
95
|
+
"""Return the repository's per-agent worktree root.
|
|
99
96
|
|
|
100
97
|
::
|
|
101
98
|
|
|
102
|
-
#
|
|
103
|
-
resolve_agent_worktree_root("grok")
|
|
99
|
+
# repo_root=/srv/app, agent_slug=grok
|
|
100
|
+
resolve_agent_worktree_root(Path("/srv/app"), "grok")
|
|
101
|
+
# -> /srv/app/.claude/worktrees/grok
|
|
102
|
+
|
|
103
|
+
Every worktree sits under the repository it branches from, so a worktree
|
|
104
|
+
travels with its repository and each agent keeps its own subdirectory.
|
|
104
105
|
|
|
105
106
|
Args:
|
|
107
|
+
repo_root: Absolute path of the repository the branch comes from.
|
|
106
108
|
agent_slug: Short host label (one path segment).
|
|
107
109
|
|
|
108
110
|
Returns:
|
|
109
111
|
Directory that should hold per-branch worktree folders.
|
|
110
112
|
"""
|
|
111
|
-
|
|
112
|
-
user_profile = os.environ.get(USERPROFILE_ENV_VAR)
|
|
113
|
-
if user_profile:
|
|
114
|
-
return Path(user_profile).joinpath(
|
|
115
|
-
*ALL_WINDOWS_USER_SCRATCH_PARTS,
|
|
116
|
-
agent_slug,
|
|
117
|
-
)
|
|
118
|
-
return Path(tempfile.gettempdir()) / agent_slug
|
|
113
|
+
return repo_root.joinpath(*ALL_REPOSITORY_WORKTREE_ROOT_PARTS, agent_slug)
|
|
119
114
|
|
|
120
115
|
|
|
121
116
|
def resolve_unique_worktree_path(preferred_path: Path) -> Path:
|
|
@@ -181,13 +176,33 @@ def create_fresh_branch(
|
|
|
181
176
|
::
|
|
182
177
|
|
|
183
178
|
create_fresh_branch("fix/x", Path("."), "grok", "origin/main")
|
|
179
|
+
|
|
180
|
+
The caller's working tree is never checked out. The worktree lands under
|
|
181
|
+
the repository's ``.claude/worktrees/<agent>/<branch>``, suffixed ``-2``,
|
|
182
|
+
``-3``, … when that path is already taken.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
branch_name: Branch to create; must be a safe relative path.
|
|
186
|
+
repo_path: Any path inside the repository the branch comes from.
|
|
187
|
+
agent_slug: Short host label naming the worktree-root subdirectory.
|
|
188
|
+
base_ref: Ref the branch starts from, such as ``origin/main``.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
The success payload: branch, worktree_path, base_ref, base_commit,
|
|
192
|
+
agent, and repo_root.
|
|
193
|
+
|
|
194
|
+
Raises:
|
|
195
|
+
ValueError: When the branch name or the agent slug is unsafe.
|
|
196
|
+
RuntimeError: When git refuses the fetch or the worktree add.
|
|
184
197
|
"""
|
|
185
198
|
cleaned_branch = _require_safe_branch_name(branch_name)
|
|
186
199
|
normalized_agent_slug = _normalize_agent_slug(agent_slug)
|
|
187
200
|
resolved_base_ref, repo_root, base_commit = _resolve_branch_base(
|
|
188
201
|
repo_path, base_ref,
|
|
189
202
|
)
|
|
190
|
-
worktree_path = _allocate_worktree_path(
|
|
203
|
+
worktree_path = _allocate_worktree_path(
|
|
204
|
+
cleaned_branch, normalized_agent_slug, repo_root,
|
|
205
|
+
)
|
|
191
206
|
create_worktree_branch(
|
|
192
207
|
repo_root,
|
|
193
208
|
branch_name=cleaned_branch,
|
|
@@ -241,8 +256,11 @@ def _require_safe_branch_name(branch_name: str) -> str:
|
|
|
241
256
|
return cleaned_branch
|
|
242
257
|
|
|
243
258
|
|
|
244
|
-
def _allocate_worktree_path(
|
|
245
|
-
|
|
259
|
+
def _allocate_worktree_path(
|
|
260
|
+
branch_name: str, agent_slug: str, repo_root: Path,
|
|
261
|
+
) -> Path:
|
|
262
|
+
agent_worktree_root = resolve_agent_worktree_root(repo_root, agent_slug)
|
|
263
|
+
agent_worktree_root.mkdir(parents=True, exist_ok=True)
|
|
246
264
|
preferred_path = agent_worktree_root / branch_name
|
|
247
265
|
_assert_path_is_under_agent_root(
|
|
248
266
|
candidate_path=preferred_path,
|
|
@@ -324,7 +342,7 @@ def _parse_arguments() -> argparse.Namespace:
|
|
|
324
342
|
parser.add_argument(
|
|
325
343
|
"--agent",
|
|
326
344
|
default=None,
|
|
327
|
-
help="Host label for
|
|
345
|
+
help="Host label for .claude/worktrees/<agent>/ (default: detect from environment).",
|
|
328
346
|
)
|
|
329
347
|
parser.add_argument(
|
|
330
348
|
"--base",
|
package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/fresh_branch_cli_constants.py
CHANGED
|
@@ -23,9 +23,7 @@ ALL_AGENT_DETECTION_MARKERS: tuple[tuple[str, str], ...] = (
|
|
|
23
23
|
PATH_SEGMENT_CURRENT = "."
|
|
24
24
|
PATH_SEGMENT_PARENT = ".."
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
ALL_WINDOWS_USER_SCRATCH_PARTS = ("AppData", "Local", "Temp")
|
|
28
|
-
USERPROFILE_ENV_VAR = "USERPROFILE"
|
|
26
|
+
ALL_REPOSITORY_WORKTREE_ROOT_PARTS = (".claude", "worktrees")
|
|
29
27
|
|
|
30
28
|
MAXIMUM_UNIQUE_PATH_ATTEMPTS = 100
|
|
31
29
|
UNIQUE_PATH_SUFFIX_START = 2
|