ace-handbook 0.29.0 → 0.30.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72ea6d4981e8c7686fa38ae9f12c868bb0d910b148ee8150d4de55b7d5ccc07e
4
- data.tar.gz: aa19a72eb4faca05a8ddc78bfdff8dd1a19c7e5875ffae32da1d59097aec8630
3
+ metadata.gz: b94315e917fb596807bf3d96a19c8ae761c1072a123db529f594cb62bc04a067
4
+ data.tar.gz: 8ef249b59bba855eb0049d29d55214fdc53617b7087e20b508eaaf378444082c
5
5
  SHA512:
6
- metadata.gz: 1c0ba11fdb8f55c87ce15642d34746c994b38480e920f98f2c3bfb447092fdaba2e9e69efac60d4a13e588242326db28c99d2b9b130093d9e331f05fd7862233
7
- data.tar.gz: 82ccfe66ee207de57e86524684a28ba4f518a1c8ca252c49cc89dab3706ac7f305ddf56532883ffe64cc26ff8a7d8a0b618f22a48d247553387182414bd9e59f
6
+ metadata.gz: 79af4b6242830f25a4db6e81433f32b3737a477425b3f2c4c9c62dfae58bb6ea770433a9ccf208fb886d614eb9840f72fb50be03159b83564e865a2e6d992516
7
+ data.tar.gz: e0c1db8530a0b95f2ee7bccc8b3c115e88c8fdcdcfc3fd2f086d4aa709e3c3647833c337d99ef44dd10e24e54c77e0f5f1780f47f3ebb29e6e140291442c25ad
data/CHANGELOG.md CHANGED
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.30.0] - 2026-07-15
11
+
12
+ ### Added
13
+ - Added agents projection coverage fields to `ace-handbook status` JSON and table output, including projection policy,
14
+ excluded skill count, and the reason for curated projections.
15
+
16
+ ### Technical
17
+ - Added fast and E2E regression coverage for the neutral agents projection status contract.
18
+
19
+ ## [0.29.1] - 2026-06-30
20
+
21
+ ### Fixed
22
+ - Treated skills targeting the legacy full provider set (`claude`, `codex`, `gemini`, `opencode`, `pi`) as compatible
23
+ with the default `agents` projection, so installed common ACE workflow skills such as `as-git-commit` are written to
24
+ `.agents/skills/` by plain `ace-handbook sync`.
25
+
10
26
  ## [0.29.0] - 2026-06-30
11
27
 
12
28
  ### Added
@@ -7,12 +7,19 @@ module Ace
7
7
  module Molecules
8
8
  class SkillProjection
9
9
  class << self
10
+ LEGACY_PROVIDER_TARGETS = %w[claude codex gemini opencode pi].freeze
11
+
10
12
  def projection_targets(frontmatter, registry:)
11
13
  integration = frontmatter.fetch("integration", {})
12
14
  targets = integration["targets"]
13
15
  return registry.providers if targets.nil? || targets.empty?
14
16
 
15
- Array(targets).map(&:to_s).select { |provider| registry.known?(provider) }
17
+ known_targets = Array(targets).map(&:to_s).select { |provider| registry.known?(provider) }
18
+ if registry.known?("agents") && legacy_provider_target_set?(known_targets)
19
+ known_targets = known_targets + ["agents"]
20
+ end
21
+
22
+ known_targets.uniq
16
23
  end
17
24
 
18
25
  def projected_frontmatter(frontmatter, provider:)
@@ -32,6 +39,10 @@ module Ace
32
39
 
33
40
  private
34
41
 
42
+ def legacy_provider_target_set?(targets)
43
+ targets.sort == LEGACY_PROVIDER_TARGETS.sort
44
+ end
45
+
35
46
  def deep_copy(data)
36
47
  Marshal.load(Marshal.dump(data))
37
48
  end
@@ -35,6 +35,9 @@ module Ace
35
35
  entry.fetch("outdated").to_s,
36
36
  entry.fetch("missing").to_s,
37
37
  entry.fetch("extra").to_s,
38
+ entry.fetch("projection_policy", "").to_s,
39
+ entry.fetch("excluded_count", "").to_s,
40
+ entry.fetch("policy_reason", "").to_s,
38
41
  entry.fetch("relative_output_dir")
39
42
  ]
40
43
  end
@@ -48,19 +51,21 @@ module Ace
48
51
  ["IN_SYNC", *rows.map { |row| row[5] }].map(&:length).max,
49
52
  ["OUTDATED", *rows.map { |row| row[6] }].map(&:length).max,
50
53
  ["MISSING", *rows.map { |row| row[7] }].map(&:length).max,
51
- ["EXTRA", *rows.map { |row| row[8] }].map(&:length).max
54
+ ["EXTRA", *rows.map { |row| row[8] }].map(&:length).max,
55
+ ["POLICY", *rows.map { |row| row[9] }].map(&:length).max,
56
+ ["EXCLUDED", *rows.map { |row| row[10] }].map(&:length).max,
57
+ ["REASON", *rows.map { |row| row[11] }].map(&:length).max,
58
+ ["PATH", *rows.map { |row| row[12] }].map(&:length).max
52
59
  ]
53
60
 
54
- header = format(
55
- "%-#{widths[0]}s %-#{widths[1]}s %-#{widths[2]}s %#{widths[3]}s %#{widths[4]}s %#{widths[5]}s %#{widths[6]}s %#{widths[7]}s %#{widths[8]}s %s",
56
- "PROVIDER", "ENABLED", "TYPE", "EXPECTED", "INSTALLED", "IN_SYNC", "OUTDATED", "MISSING", "EXTRA", "PATH"
57
- )
58
- lines = rows.map do |provider, enabled, type, expected, installed, in_sync, outdated, missing, extra, path|
59
- format(
60
- "%-#{widths[0]}s %-#{widths[1]}s %-#{widths[2]}s %#{widths[3]}s %#{widths[4]}s %#{widths[5]}s %#{widths[6]}s %#{widths[7]}s %#{widths[8]}s %s",
61
- provider, enabled, type, expected, installed, in_sync, outdated, missing, extra, path
62
- )
61
+ right_aligned = (3..8).to_a + [10]
62
+ formats = widths.each_index.map do |index|
63
+ right_aligned.include?(index) ? "%#{widths[index]}s" : "%-#{widths[index]}s"
63
64
  end
65
+ table_format = formats.join(" ")
66
+ headers = %w[PROVIDER ENABLED TYPE EXPECTED INSTALLED IN_SYNC OUTDATED MISSING EXTRA POLICY EXCLUDED REASON PATH]
67
+ header = format(table_format, *headers)
68
+ lines = rows.map { |row| format(table_format, *row) }
64
69
 
65
70
  (summary_lines + ["", header] + lines).join("\n")
66
71
  end
@@ -102,7 +107,7 @@ module Ace
102
107
  end
103
108
  end
104
109
 
105
- {
110
+ status = {
106
111
  "provider" => provider,
107
112
  "enabled" => provider_enabled?(provider),
108
113
  "relative_output_dir" => relative_output_dir,
@@ -116,6 +121,19 @@ module Ace
116
121
  "missing" => (expected.keys - installed_names).size,
117
122
  "extra" => extra
118
123
  }
124
+
125
+ status.merge!(projection_coverage(skills, expected)) if provider == "agents"
126
+ status
127
+ end
128
+
129
+ def projection_coverage(skills, expected)
130
+ excluded_count = skills.size - expected.size
131
+
132
+ {
133
+ "projection_policy" => excluded_count.zero? ? "complete" : "curated",
134
+ "excluded_count" => excluded_count,
135
+ "policy_reason" => excluded_count.zero? ? nil : "provider-specific targeting"
136
+ }
119
137
  end
120
138
 
121
139
  def expected_projection_map(provider, skills)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ace
4
4
  module Handbook
5
- VERSION = '0.29.0'
5
+ VERSION = '0.30.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ace-handbook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.29.0
4
+ version: 0.30.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Czyz
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-06-30 00:00:00.000000000 Z
10
+ date: 2026-07-15 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: ace-support-config