ace-git-worktree 0.27.1 → 0.27.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1214
- data/README.md +7 -0
- data/docs/usage.md +5 -0
- data/lib/ace/git/worktree/atoms/task_id_extractor.rb +33 -18
- data/lib/ace/git/worktree/organisms/worktree_manager.rb +2 -2
- data/lib/ace/git/worktree/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
> Works with: Claude Code, Codex CLI, OpenCode, Gemini CLI, pi-agent, and more.
|
|
16
16
|
|
|
17
|
+
> **State owner:** `.ace-wt/` -- one worktree per project task, owning only the
|
|
18
|
+
> Git checkout and branch. Task metadata stays in `.ace-tasks/`; assignment
|
|
19
|
+
> plans stay in `.ace-local/assign/`. See [docs/lab-flow.md](../docs/lab-flow.md).
|
|
20
|
+
|
|
17
21
|
[Getting Started](docs/getting-started.md) | [Usage Guide](docs/usage.md) | [Handbook - Skills, Agents, Templates](docs/handbook.md)
|
|
18
22
|
|
|
19
23
|

|
|
@@ -36,6 +40,9 @@
|
|
|
36
40
|
|
|
37
41
|
**Orchestrate parallel task work with ace-overseer** - pair with [ace-overseer](../ace-overseer) to spin up worktrees per task, drive agents in parallel, and prune finished worktrees automatically.
|
|
38
42
|
|
|
43
|
+
> **Planned (L6):** the private overseer queue that hands one worktree between
|
|
44
|
+
> worker, reviewer, and integrator -- not available yet.
|
|
45
|
+
|
|
39
46
|
## Testing Contract
|
|
40
47
|
|
|
41
48
|
Run package tests with the restarted deterministic + scenario split:
|
data/docs/usage.md
CHANGED
|
@@ -74,6 +74,11 @@ Created task worktree and branch for 081
|
|
|
74
74
|
|
|
75
75
|
**Next steps:** Run `cd "$(ace-git-worktree switch 081)"` to move into the new worktree.
|
|
76
76
|
|
|
77
|
+
Worktree creation is role- and folder-name-agnostic: it does not inspect
|
|
78
|
+
`.gitignore` and does not classify management tasks. If a requested worktree
|
|
79
|
+
does not contain the named task, the executor reports the missing task;
|
|
80
|
+
preparing a correct delegation is the requester's responsibility.
|
|
81
|
+
|
|
77
82
|
### Scenario 2: Review a Pull Request in Its Own Worktree
|
|
78
83
|
|
|
79
84
|
**Goal:** Create a dedicated workspace for PR review or patching, on any
|
|
@@ -15,13 +15,24 @@ module Ace
|
|
|
15
15
|
# TaskIDExtractor.extract({id: "v.0.9.0+task.121"}) # => "121"
|
|
16
16
|
# TaskIDExtractor.extract({id: "v.0.9.0+ace-t.121.01"}) # => "121.01"
|
|
17
17
|
# TaskIDExtractor.extract({id: "v.0.9.0+t.121"}) # => "121"
|
|
18
|
+
# TaskIDExtractor.extract({id: "8xh.t.ddd.0.0"}) # => "ddd.0.0"
|
|
18
19
|
#
|
|
19
20
|
# @example Normalize a task reference string
|
|
20
21
|
# TaskIDExtractor.normalize("v.0.9.0+task.121.01") # => "121.01"
|
|
21
22
|
# TaskIDExtractor.normalize("task.121") # => "121"
|
|
22
23
|
# TaskIDExtractor.normalize("ace-t.121") # => "121"
|
|
23
24
|
# TaskIDExtractor.normalize("121.01") # => "121.01"
|
|
25
|
+
# TaskIDExtractor.normalize("8xh.t.ddd.0.0") # => "ddd.0.0"
|
|
24
26
|
class TaskIDExtractor
|
|
27
|
+
# B36TS full id with an arbitrary chain of subtask segments:
|
|
28
|
+
# "8xh.t.ddd" -> "ddd", "8xh.t.ddd.0" -> "ddd.0",
|
|
29
|
+
# "8xh.t.ddd.0.0" -> "ddd.0.0". Every task/subtask segment is
|
|
30
|
+
# preserved so the derived branch/worktree name is deterministic
|
|
31
|
+
# and reversible (the segment chain maps 1:1 onto the id).
|
|
32
|
+
B36TS_FULL_ID = /\A[0-9a-z]{3}\.[a-z]\.([0-9a-z]{3}(?:\.[0-9a-z]+)*)\z/
|
|
33
|
+
# Short form of the same chain, optionally inside a longer path
|
|
34
|
+
# (matched at the end): "t.ddd.0.0", "task.hy4", "/x/ace-task.121/".
|
|
35
|
+
SHORT_TASK_ID = /(?:ace-)?(?:task|t)\.([0-9a-z]{3}(?:\.[0-9a-z]+)*)\/?\z/
|
|
25
36
|
# Extract task ID from task data hash
|
|
26
37
|
#
|
|
27
38
|
# @param task_data [Hash] Task data with :id and/or :task_number
|
|
@@ -31,8 +42,9 @@ module Ace
|
|
|
31
42
|
|
|
32
43
|
# Regex with subtask support
|
|
33
44
|
if task_data[:id]
|
|
34
|
-
# B36TS full ID: "8pp.t.hy4" -> "hy4",
|
|
35
|
-
|
|
45
|
+
# B36TS full ID: "8pp.t.hy4" -> "hy4", subtasks keep every
|
|
46
|
+
# segment: "8pp.t.hy4.a" -> "hy4.a", "8xh.t.ddd.0.0" -> "ddd.0.0"
|
|
47
|
+
if (match = task_data[:id].match(B36TS_FULL_ID))
|
|
36
48
|
return match[1]
|
|
37
49
|
end
|
|
38
50
|
# Try subtask pattern first (e.g., "v.0.9.0+task.121.01" -> "121.01")
|
|
@@ -55,18 +67,17 @@ module Ace
|
|
|
55
67
|
|
|
56
68
|
# Derive the short form of a full Base36 task id.
|
|
57
69
|
#
|
|
58
|
-
# The short form is the three-character suffix plus
|
|
59
|
-
# subtask segment (numeric or
|
|
70
|
+
# The short form is the three-character suffix plus the complete
|
|
71
|
+
# subtask segment chain (each segment numeric or alphanumeric,
|
|
72
|
+
# any depth): "8xh.t.ddd.0.0" -> "ddd.0.0".
|
|
60
73
|
#
|
|
61
74
|
# @param full_id [String, nil] formatted task id (e.g. "8xg.t.k9y",
|
|
62
|
-
# "8wr.t.qk0.3")
|
|
63
|
-
# @return [String, nil] short id (e.g. "k9y", "qk0.3")
|
|
64
|
-
# argument is not a full task id
|
|
75
|
+
# "8wr.t.qk0.3", "8xh.t.ddd.0.0")
|
|
76
|
+
# @return [String, nil] short id (e.g. "k9y", "qk0.3", "ddd.0.0")
|
|
77
|
+
# or nil when the argument is not a full task id
|
|
65
78
|
def self.short_id(full_id)
|
|
66
|
-
match = full_id.to_s.strip.match(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
match[2] ? "#{match[1]}.#{match[2]}" : match[1]
|
|
79
|
+
match = full_id.to_s.strip.match(B36TS_FULL_ID)
|
|
80
|
+
match && match[1]
|
|
70
81
|
end
|
|
71
82
|
|
|
72
83
|
# Normalize a task reference string to simple ID format
|
|
@@ -78,8 +89,9 @@ module Ace
|
|
|
78
89
|
return nil if ref.empty?
|
|
79
90
|
|
|
80
91
|
# Regex patterns for recognized ACE task ID formats
|
|
81
|
-
# B36TS full ID: "8pp.t.hy4" -> "hy4",
|
|
82
|
-
|
|
92
|
+
# B36TS full ID: "8pp.t.hy4" -> "hy4", subtasks keep every
|
|
93
|
+
# segment: "8pp.t.hy4.a" -> "hy4.a", "8xh.t.ddd.0.0" -> "ddd.0.0"
|
|
94
|
+
if (match = ref.match(B36TS_FULL_ID))
|
|
83
95
|
match[1]
|
|
84
96
|
# B36TS short ref: exactly 3 lowercase alphanumeric chars (e.g., "hy4")
|
|
85
97
|
elsif match = ref.match(/\A([0-9a-z]{3})\z/)
|
|
@@ -88,11 +100,14 @@ module Ace
|
|
|
88
100
|
# Try hierarchical pattern first (e.g., "121.01", "task.121.01")
|
|
89
101
|
elsif match = ref.match(/(\d{3})\.(\d{2})(?:\b|$)/)
|
|
90
102
|
"#{match[1]}.#{match[2]}"
|
|
91
|
-
# B36TS short ref with subtask segment
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
# B36TS short ref with the whole subtask segment chain
|
|
104
|
+
# (e.g., "qk0.3", "hy4.a", "ddd.0.0")
|
|
105
|
+
elsif match = ref.match(/\A([0-9a-z]{3}(?:\.[0-9a-z]+)*)\z/)
|
|
106
|
+
match[1]
|
|
107
|
+
# Try task./t. (or ace-task./ace-t.) prefix, keeping the whole
|
|
108
|
+
# subtask segment chain (e.g. "t.ddd.0.0", "task.hy4.a",
|
|
109
|
+
# "/path/to/task.121", "ace-task.hy4/")
|
|
110
|
+
elsif (match = ref.match(SHORT_TASK_ID))
|
|
96
111
|
match[1]
|
|
97
112
|
# Try task./t. prefix in middle of path (e.g., ".cache/test/task.121")
|
|
98
113
|
# Use negative lookbehind to skip ace-task.XXX / ace-t.XXX parent directories
|
|
@@ -272,8 +272,8 @@ module Ace
|
|
|
272
272
|
# result = manager.list_all
|
|
273
273
|
# result = manager.list_all(format: :json)
|
|
274
274
|
#
|
|
275
|
-
# Programmatic inventory for internal consumers (
|
|
276
|
-
#
|
|
275
|
+
# Programmatic inventory for internal consumers (prune, switch/remove
|
|
276
|
+
# hints). The user-facing enriched table is rendered by
|
|
277
277
|
# {WorktreeListReport}, not here.
|
|
278
278
|
#
|
|
279
279
|
# @option options [Symbol] :format Optional formatting (:simple, :json)
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ace-git-worktree
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.27.
|
|
4
|
+
version: 0.27.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michal Czyz
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-10-
|
|
10
|
+
date: 2026-10-20 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ace-support-cli
|